Seeing tests pass

As you might have guessed, it's again time to run Codeception against our UserTest class:

$ ../vendor/bin/codecept run unit models/UserTest.php
Codeception PHP Testing Framework v2.0.6
Powered by PHPUnit 4.4-dev by Sebastian Bergmann.

Unit Tests (14) -----------------------------
Trying to test validate returns false if parameters are not set (testscodeceptionunitmodelsUserTest::testValidateReturnsFalseIfParametersAreNotSet)                              Ok
[snip]


Time: 3.61 seconds, Memory: 28.75Mb

OK (27 tests, 53 assertions)

You should have all tests passing without problems, and you should also be able to fix them in case an error is raised.

If we decide to run all the tests, including those that were already there, we might see that some tests are not passing anymore. Don't worry, this is quite normal as we've changed the way the User model works and behaves internally. In particular, the error I'm getting is the following regarding LoginFormTest, but Codeception/PHPUnit is quite prompt in informing us what's wrong:

There was 1 error:

---------
1) testsunitmodelsLoginFormTest::testLoginCorrect | user should be able to login with correct credentials
yiiaseInvalidParamException: Hash is invalid.

                                     
FAILURES!                            
Tests: 31, Assertions: 64, Errors: 1.

As I've underlined previously, it's quite important to fix any tests that do not work well. This will make us understand if we've touched anything that wasn't meant to break or that can potentially break when committing our changes.

Using global fixtures

In this case, it's quite clear that our tests have impacted the state of the database: The solution will be able to create a new fixture with the expected data for the admin user, which replicates what the migration is doing, and to update LoginFormTest and UserTest.

We will now use the default fixture user.php as the global fixture with the admin user, as follows:

// tests/codeception/unit/fixtures/data/user.php

return [
    'admin' => [
        'id' => 1,
        'username' => 'admin',
        'password' => Yii::$app->getSecurity()->generatePasswordHash('admin'),
        'authkey' => 'valid authkey'
    ]
];

The previous fixture will be renamed as userModels.php; it contains additional users that we might end up adding to our application in the future. The code for doing so is as follows:

return [
    'user_basic' => [
        'username' => '-=[ valid username ]=-',
        'password' => 'This is a valid password!!!',
        'authkey' => '00%am|%lk;@P .'
    ],
    'user_accessToken' => [
        'username' => '-=[ valid username ]=-',
        'password' => 'This is another valid password!!! :) <script></script>',
        'authkey' => uniqid()
    ],
    'user_id' => [
        'id' => 4,
        'username' => '-=[ valid username ]=-',
        'password' => 'This is another valid password!!! :)',
        'authkey' => uniqid()
    ],
];

We could have fallen into the trap of just amending the initial fixture to contain the admin user, which would have solved the problem but would have made multiple tests rely on fixtures that were designed for specific tests. So, let's try to keep things as separate and independent as possible.

Now, we can load the previously mentioned fixture in LoginFormTest as a global fixture, as follows:

// tests/codeception/unit/models/LoginFormTest.php

public function globalFixtures()
{
    return [
        'user' => UserFixture::className(),
    ];
}

Furthermore, we can amend the previously implemented methods to load the fixtures in the UserTest, as follows:

// tests/codeception/unit/models/UserTest.php

public function globalFixtures()
{
    return [
        'user' => UserFixture::className(),
    ];
}

public function fixtures()
{
    return [
        'user' => [
            'class' => UserFixture::className(),
            'dataFile' => '@app/tests/codeception/unit/fixtures/data/userModels.php'
        ]
    ];
}

Our new fixtures() implementation will need to expand on the parameters passed and define both class and dataFile; otherwise, it won't load it properly.

The globalFixtures() method is run before the fixtures() method, which means that the $this->user variable will only contain the latest fixtures and not the admin.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset