Codeception Testing with Yii Framework 2.0 [Day 11]

Today’s Objective(s)

  1. Try to use the entire $I->wantTo(‘load all values’); style of Codeception
    1. Learn how to stub a class in Unit testing
  2. Research executing tests and viewing results from a browser
  3. Research best practices for Unit testing in Yii
  4. Research best pracices for acceptance/functional testing in Yii

Introduction

I like the style of this sort of code for testing:

$I->amOnPage('/');
$I->click('Login');
$I->fillField('Username', 'Miles');
$I->fillField('Password', 'Davis');
$I->click('Enter');
$I->see('Hello, Miles', 'h1');

Although I’ve come to realise that these are only for acceptance/functional tests, which are scheduled for learning further down the road. So I think for today I’ll focus on stubbing.

What is a stub?

A stub is basically a mock of a class that you would like to test in which you fake certain functions and make them return specific values to help with unit testing another function (At least this is how I’m understanding it at the moment). So for today I’m just going to override the functions we’ve already made and make them return values of my choosing and just test that those values are returned.

With the research I’ve done so far, I’ve found out that Codeception’s Stub class (A wrapper over PHPUnit mocking framework) doesn’t play well with Yii (Here are the issues on github #5210 and #1694), which is a shame. Based on the documentation and reference it could make things rather simple. But I must carry on with what works, and I’m sure using the basic PHPUnit mocks won’t be that bad.

Stubbing MySimpleModel

I made the following unit test:

public function testMockingMySimpleModel()
{
    $this->specify('test mocking the model', function () {
        $modelMock = $this->getMockBuilder('app\models\MySimpleModel')
            ->getMock();
        $modelMock->method('string')->willReturn('aString');
        expect('should return "aString"', $modelMock->string())->equals('aString');
        $modelMock->method('bool')->willReturn(true);
        expect('should return true', $modelMock->bool(true))->true();
    });
}

And the test runs through successfully. This is very useful… although my initial thought that it would just override the specified functions and all other functions would still be usable was incorrect. The only functions that can be called from the mocked object are those specified AND any attempt to call other functions throws errors, which is extremely useful!

Now if your Class is reliant on another Class or object to complete it’s run through, you could mock that Class and specify exactly what should be returned from the function call. Allowing you to be able to predict precisely what your Class’s functions should return and you can specify that functions in the mocked object have to be called, further documentation on that can be found here: PHPUnit documentation on test-doubles.

 

Conclusion

A rather productive evening, on top of getting a basic understanding of PHPUnit’s mocking framework, I learned that my assumptions can be wrong and when wrong the truth can be even more useful :)

Upcoming Objective(s)

  1. Research executing tests and viewing results from a browser
  2. Research best practices for Unit testing in Yii
  3. Research best pracices for acceptance/functional testing in Yii

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>