Mocking drupal database queries
formatting issue will update the code examples soon
I have a Class I want to test with phpunit but it makes several queries to a drupal database. I rather not bootstrapdrupal just to make sure this Class is returning the results as expected.
For example the SiteClass has a method called index. That method takes the uuid for a user and finds all the sites related to that user. Then using that uuid I have some other non drupal data that relates to it. So my class might look like this
//Foo.php
public function getSitesAndOtherDataForUser($uuid) {
$output = db_query(some query here);
return array('data' => $output)
}
But this is hard to test quickly in phpunit without touching the database. But I do not want to test the database. I know db_query works. I know the database layer works. I just want to verify this class is getting the request, getting information and then passing me back the right data format.
One way to do that is to make a Repository class that wraps all your database queries into methods.
So the class SiteClass has a constructor that allows the injection of the repository class for example
//Foo.php
public function __construct(SiteRepository $repo = null)
{
$this->repo = ($repo == null) ? new SiteRepository() : $repo;
}
This then turns the above function into
//Foo.php
public function getSitesAndOtherDataForUser($uuid) {
$output = $this->repo->getSitesForUserUuid($uuid)
return array('data' => $output)
}
And this then allows me to instantiate in a phpunit test the same Repo but using Mockery so my unit test would look like this
//FooTest.php
public function setUp()
{
$this->repo = Mockery::mock('SiteRepository')
}
And later call to that method in the mocked class
//FooTest.php
public function test_getSitesAndOtherDataForUser()
{
$this->repo->shouldReceive('getSitesForUserUuid')->once()->andReturn(array(1,2,3));
}
This then allows me to quickly test how my code is dealing with the output. Maybe there is a filter, or other relations I am trying to pull in. As far as testing that the data structure is correct etc I save that for a test for that.
The Repository Class can look like this if using EntityQuery
//SiteRepository.php
public $eq;
function __construct(\EntityFieldQuery $eq = null) {
$this->eq = ($eq == null) ? new \EntityFieldQuery() : $eq;
}
//Later on I can offer a method
functiongetSitesForUserUuid($uuid){
$this->eq = do some query
}
//if we are not using EQ then just do your db_query in there
function getSitesForUserUuid($uudi) {
$results = db_query(foo);
return $results;
}
comments powered by Disqus