Norway


The other day I came across the following code in a project:

class Users
{
    public function __construct(PDO $pdo)
    {
        $this->pdo = $pdo;
    }

    public function getAllUsers()
    {
        $stmt = $this->pdo->prepare('SELECT * FROM users');
        return $stmt->fetchAll();
    }
}

And the following was a test written to test this bit of code:

class UserTest extends TestCase
{
    public function testGetAllUsers()
    {
        $pdo = m::mock(PDO::class);
        $stmt = m::mock(PDOStatement::class);
        
        $pdo->shouldReceive(‘prepare’)->andReturn($stmt);
        $pdoStmt->shouldReceive(‘fetchAll’)->andReturn($userArray);

        $users = new Users($pdo);
        $result = $users->getAllUsers();
        
        $this->assertEquals($userArray, $users);
    }
}

Note that I have omitted the of the User class, as well as the Users array that is returned in the test.

This test will in fact provide us with 0% code coverage of the getAllUsers() method. But unfortunately, for any practical purpose, this unit test is completely .

This unit test is useless because instead of testing the interworkings of the getAllUsers() method, it’s actually testing Mockery. From the first lines of the test, we’re creating mocks of PDO and PDOStatement, and we’re passing those mocks into the Users class. What we’re really testing is that Mockery properly returns an array; we never touch the database.

If getAllUsers() actually *did* something, like processed the users in some way, it would be worth mocking and testing appropriately for the various conditions of the algorithm. That is not the case here.

Too often, in the search for 100% unit test code coverage, I see like this get written. They don’t serve a practical purpose, except to meet the test coverage goal. Worse, they don’t actually improve the quality of the application.

Instead of writing a unit test here, we would be better served by writing an integration test, or a functional test. These tests would require us to interact directly with the database, but would provide far more valuable information about the health and status of our application. A useless unit test provides us with little if any benefit; a useful functional test provides us with tremendous advantages.

Writing useful tests is challenging and requires skill and determination. And avoiding these kinds of useless unit tests helps ensure that the tests that are written will be useful and beneficial in the future.

Frustrated with your company’s development practices?

You don’t have to be!

No what the issues are, they can be fixed. You can begin to shed light on these issues with my handy checklist.

Plus, I’ll help you with strategies to approach the issues at the organization level and “punch above your weight.”



Source link

LEAVE A REPLY

Please enter your comment!
Please enter your name here