Using Codeception as your testing framework of choice? Did you know it’s really easy to test Zend Expressive TableGateway classes? It’s almost painfully easy. This tutorial walks you through, step-by-step.
Using Codeception as your testing framework of choice? Did you know it’s really easy to test Zend Expressive TableGateway classes? It’s almost painfully easy. This tutorial walks you through, step-by-step.
But first, why would you want to do database testing? After all, even the PhpUnit manual suggests that database testing isn’t easy; primarily because you need to take care of the following things:
- The database schema and tables
- Inserting the rows required for the test into these tables
- Verifying the state of the database after your test has run
- Cleanup the database for each new test
If you’ve ever tried to do it before, you’ll know that it isn’t easy, especially if you’re integrating it into a project which has loads of existing tests, but hasn’t had database testing so far.
Actually, it can start to push you round the twist, like it was for me, if you’re not used to it. But, with a little discipline and determination, using Codeception, and a recent module for Zend Expressive, you’re all sorted!
In a nutshell, there’s only 5 things you need to do. Let’s work through them.
One of the core features of Codeception is to be able to run a database dump file on your configured database, by default called tests/_data/dump.sql
before each test, and optionally clean up afterwards. So let’s do that first.
If you don’t have a database dump of your database, make one and store it there. Assuming that you’re using MySQL, run the command mysqldump db_name > db.dump.sql
which will create the dump file.
Alternatively, you can use tools such as Navicat, which have excellent GUIs and make the task of creating dump files, virtually, painless.
After that, you need to update the Codeception configuration files to load the dump file, and clean up afterwards. Here’s how to do that. In tests/unit.suite.yml
ensure there’s a Db configuration section, similar to that below.
class_name: UnitTester
modules:
enabled:
- Asserts
- \Helper\Unit
- Db:
dsn: 'pgsql:host=localhost;port=5432;dbname=database_name'
user: ‘user_name'
password: ‘my_password’
dump: tests/_data/dump.sql
cleanup: true
populate: true
This will load the database with the data from tests/_data/dump.sql
before each test, and clean it up after each test.
2. Enable the Zend Expressive Module
With the dump file configured, we now need to load the Zend Expressive Codeception module. To do that, open tests/unit.suite.yml
and add ZendExpressive
to the list of enabled modules. Here’s a sample of what it may look like, depending on your configuration.
class_name: UnitTester
modules:
enabled:
- Asserts
- \Helper\Unit
- ZendExpressive
3. Create a Unit Test
Now that we have everything in place, it’s time to create a test which will work with your database. To do that, run the following command php vendor/bin/codecept generate:test unit TableGateway/UsersTableGatewayTest
. This will generate a new, empty, unit test under tests/unit/TableGateway
, creating the TableGateway directory if it doesn’t exist. It will, initially, look like the following:
<?php
namespace TelcoSwitchTests\Unit;
class UsersTableGatewayTest extends \Codeception\TestCase\Test
{
protected $tester;
protected function _before()
{
}
protected function _after()
{
}
// tests
public function testMe()
{
}
}
Now we need to create a local variable which will be an instance of our database service. To do that, add a new member variable, called usersTable
. To instantiate it, we’ll then implement the _before()
method, which runs before all the tests.
There, we’ll use the ZendExpressive module to get access to the application’s DI container, and retrieve the UserTable service - which is our TableGateway class which interacts with the user table. It will look as follows:
protected function _before()
{
$this->usersTable = $this->getModule('ZendExpressive')
->container
->get(UserTable::class);
}
With this done, we’re now ready to start calling the methods on it.
4. Add Your Test
Let’s say that we have a method on that class, which retrieves a user by their id, a method which is defined as follows:
/**
* @param int $id
* @return null|\Zend\Db\ResultSet\ResultSetInterface
*/
public function fetchById($id)
{
if (!empty($id)) {
$select = $this->tableGateway->getSql()->select();
$select->columns(
[
"id", "addressid", "first", "last", "position",
"email", "telephone", "username", "usertype",
"password"
]
)->join(
'tblresellerpartners',
'tblresellerpartners.partner_id = id'
)->where([
"tblresellerpartners.reseller_id" => (int)$id
]);
return $this->tableGateway->selectWith($select);
}
}
In our dump.sql file, we’ve listed a number of users, and one has the id 1
. So we know that if we call this method, supplying 1
as the id, then it should return a valid record. Let’s now test that that works.
In UsersTablegatewayTest
, we’ll add a new method, as follows:
/**
* @covers ::fetchById
*/
public function testCanFetchUserById()
{
$result = $this->usersTable->fetchById(21);
$this->assertInstanceOf(ResultSetInterface::class, $result);
$this->assertCount(1, $result);
}
5. Run the Test
Now that everything’s in place, it’s time to execute the test. From your terminal, run the following command to launch the test php vendor/bin/codecept run unit
. That will then run all the unit tests, our new one included.
All being well, both assertions will pass, verifying that the code works as anticipated. After that, you could add a range of other assertions, such as passing an invalid id, or one where there’s no matching user.
That’s a Wrap
And that’s how to perform database testing in your Zend Expressive applications, not mocking, using Codeception. I hope that it helps you validate that your database classes do do what you expect that they should. If you need any further information on Codeception, check out the website, or the other Codeception articles here on the blog.
Join the discussion
comments powered by Disqus