I have been using PHPUnit for a while now, but suddenly hit a big wall: mocking LDAP. I have a small abstraction layer for communicating with an LDAP server using the default LDAP PHP extension. Right now, i have no idea on how to mock the connection and functionalities of the extension in order to properly test my class.
Filesystem and Database mocks are quite common and easy to setup, but what about directory servers? 🙁
You should mock your LDAP adapter, not the PHP extension. Filesystem and Database mocks work the same way… they don’t actually create file-systems or databases, they just represent the class that normally interacts with those data-sources and mimic certain behaviors as if there really existed.
For example:
Normally, this call would go out to the database and query for user 12345. However, we’ve mocked the PDO adapter and told it to respond with data when its
query()orexecute()methods are invoked with expected parameters. So, while it appears that we’ve mocked the entire database, all we’ve really done is mocked the class closest to the database but furthest from your own code.Hopefully you’re using an authentication system with an LDAP adapter that you can swap out with a mock. Or a wrapper class for PHP’s ldap functions.
Update
The big problem is that you’re using basic ldap functions in almost every method. Not a problem with the code really.. but it’s difficult to unit-test. I’ve gotten around that by creating a single method that takes care of all that communication and made my assertions against that:
(disclaimer: this code makes no logical sense and won’t work at all.. only for example purposes)
So every
ldap_*function is invoked from the same_callLdap()method. If you wanted to test theauthenticate()method, all you would have to do is:_callLdapmethod and assert that it was called once with the right argumentsauthenticate()like you normally wouldSomething like this:
This test asserts that the
_callLdapmethod is invoked once with paramsarray('ldap_bind', 'mike', 'password')insuring thatauthenticate()is functioning properly