Mocking LDAP Connection for PHPUnit Test Suite

I've been using PHPUnit for a while, but suddenly hit a big wall: mocking LDAP. I have a small abstraction layer for communicating with an LDAP server using the default LDAP extension. Right now, I don't know how to mock the connection and extension functionality in order to properly test my class.

File system and Database mocks are pretty common and easy to configure, but what about directory servers ?:(

+3


source to share


2 answers


You should make fun of your LDAP adapter, not the PHP extension. The filesystem and database engines work the same way ... they don't actually create filesystems or databases, they just represent a class that usually interacts with these data sources and mimics some of the behavior as if they actually existed.

For example:

// Load user 12345
$user = UserModel::find(12345); 

      

Usually this call would go out to the database and query user 12345. However, we mocked the PDO adapter and told it to respond with data when its methods query()

or execute()

are called with the expected parameters. we did indeed mock the class closest to the database but farthest from your own code.

Hopefully you are using an LDAP adapter authentication system that you can exchange with the layout. Or a wrapper class for PHP ldap functions.

Update

The big problem is that you are using basic ldap functions for almost every method. Not really a problem with the code, but it is difficult to unit test. I got around this by creating a single method that takes care of this whole post and made my assertions against that:



(disclaimer: this code makes no logical sense and will not work at all ... just for example)

class LDAP_Auth {

  public function authenticate($username, $password) {
    // Extra business logic or other things that need to be tested
    return $this->_callLdap('ldap_bind', $username, $password);
  }

  protected function _callLdap() {
    $args = func_get_args();
    $functionName = array_shift($args); // First argument should be the function name

    return call_user_func_array($functionName, $args);
  }
}

      

Thus, every function ldap_*

is called from the same method _callLdap()

. If you want to test a method authenticate()

, all you have to do is:

  • create a mock object of the class itself
  • mock method _callLdap

    and assert that it was called once with the correct arguments
  • then call authenticate()

    as usual

Something like that:

$ldapMock = $this->getMock('LDAP_Auth', array('_callLdap');
$ldapMock->expects($this->once())
  ->method('_callLdap')
  ->with(array('ldap_bind', 'mike', 'password'))
  ->will($this->returnValue(true));

$ldapMock->authenticate('mike', 'password');

      

This test asserts that the method _callLdap

is called once with parameters array('ldap_bind', 'mike', 'password')

ensuring that it authenticate()

works fine

+5


source


Alternatively, ou can use the UndIDID Ldap SDK storage server to create a functioning directory server for testing purposes. See also: In a memory directory server .



+1


source







All Articles