Unit Testing Zend Expressive Database Classes with Codeception

"Unit Testing Zend Expressive Database Classes with Codeception"

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:

  1. The database schema and tables
  2. Inserting the rows required for the test into these tables
  3. Verifying the state of the database after your test has run
  4. 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.

1. Configure the Database Dump File

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
        - 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
        - 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:


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')

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();
                    "id", "addressid", "first", "last", "position",
                    "email", "telephone", "username", "usertype",
                'tblresellerpartners.partner_id = id'
                "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.

About Matthew

Matthew Setter Matthew Setter is a PHP & Zend Framework specialist. If you're in need of a custom software application, need to migrate an existing legacy application, or want to know your current application's GPA - get in touch.

Don’t Miss The Next Tutorial!

Drop your email in the box below, and get it straight to your inbox, PLUS exclusive content only available by email. No spam, and you can unsubscribe at any time.