1

How do I query the database when using PHPunit? This is my current attempt.

 /**
   * Testing to see if table is installed
   */
  public function testTableTest() {
   $connection = $this->getMock('Drupal\Tests\Core\Database\Stub\StubPDO');
    //-- What do I do next to query the database

    $query = $connection->query("SHOW TABLES LIKE {does_my_table_exist}");


    $expected = 'does_my_table_exist';
    $result = $query;
    $this->assertEquals($expected, $result);
  }

1 Answer 1

3

When you're using mocks in unit tests (see https://stackoverflow.com/questions/2665812/what-is-mocking), you yourself specify all the interaction that happens with the mocked object. In the simplest example, you can just specify exactly what the mock expects to receive, and what it will return:

$connection = $this->getMock('\Drupal\Core\Database\Connection', []);
$connection->method('query')
  ->with('SHOW TABLES LIKE {does_my_table_exist}') // expect this query
  ->willReturn(
    $this->getMock('\Drupal\Core\Database\StatementInterface')
      ->method('rowCount') // expect the ->rowCount() to be called.
      ->willReturn(1) // pretend that there is exactly one result.
  );

$result = $connection->query('SHOW TABLES LIKE {does_my_table_exist}')->rowCount();
$this->assertEquals(1, $result); // PASS
$result = $connection->query('SHOW TABLES'); // FAIL; unexpected argument.

Note that you shouldn't normally be mocking the StubPDO class; it's only for Drupal's internal DB driver tests. When your code interacts with the database, it does so via the database (\Drupal::database()) service, which you can replace with a mock of \Drupal\Core\Database\Connection.

Edit: A good example of a core unit test that mocks the database and actually simulates interaction is core/modules/comment/tests/src/Unit/CommentStatisticsUnitTest.php. An excerpt of the setUp() function:

$this->statement = $this->getMockBuilder('Drupal\Core\Database\Driver\sqlite\Statement')
  ->disableOriginalConstructor()
  ->getMock();

$this->statement->expects($this->any())
  ->method('fetchObject')
  ->will($this->returnCallback([$this, 'fetchObjectCallback']));

$this->select = $this->getMockBuilder('Drupal\Core\Database\Query\Select')
  ->disableOriginalConstructor()
  ->getMock();

$this->select->expects($this->any())
  ->method('fields')
  ->will($this->returnSelf());

$this->select->expects($this->any())
  ->method('condition')
  ->will($this->returnSelf());

$this->select->expects($this->any())
  ->method('execute')
  ->will($this->returnValue($this->statement));

$this->database = $this->getMockBuilder('Drupal\Core\Database\Connection')
  ->disableOriginalConstructor()
  ->getMock();

$this->database->expects($this->once())
  ->method('select')
  ->will($this->returnValue($this->select));

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.