Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added shouldAllowMockingMethod method to allow non-existing methods to b... #296

Conversation

malteriesch
Copy link
Contributor

updated pull request for #173

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.14%) when pulling ee949fa on malteriesch:should-allow-specifying-methods-for-mocking into 6a6fc18 on padraic:master.

davedevelopment added a commit that referenced this pull request Mar 5, 2014
…ods-for-mocking

added shouldAllowMockingMethod method to allow non-existing methods to b...
@davedevelopment davedevelopment merged commit a32c6ad into mockery:master Mar 5, 2014
@davedevelopment
Copy link
Collaborator

Thanks!

@malteriesch
Copy link
Contributor Author

@davedevelopment @padraic
Cheers for the merge!

I like the refactoring of Mockery by the way, it is much clearer now! :)

Slightly off-topic (apologies), I would be interested to hear your opinion on something, as you clearly share my interest in TDD:
I have just, finally, pushed a mini-project to my github page that aims to make database testing easier (obviously in most cases database classes should be mocked, but at some point you still need to test that what comes out of and goes into the database is correct...)

we all have limited time so feel free to ignore this, but maybe this is something of interest to you, it made my life easier for sure...
https://github.com/malteriesch/test-db-acle

It would be good to hear some feedback, if, for example, there are use cases for this but also if there is anything 'wrong' with this approach...

@davedevelopment
Copy link
Collaborator

@malteriesch it's not my style, but if it's working for you, go for it.

I usually create manual factories for my integration tests, that would look something like this:

<?php

class UserFixture
{
    public function createUser(array $data)
    {
        $data = [
            'email' => isset($data['email']) ? $data['email'] : "user" . rand(0,100) . "@example.com",
            'date_of_birth' => isset($data['date_of_birth']) ? to_date_time($data['date_of_birth']) : new DateTime("-30 years"),
             // other defaults for everything
        ];

        $this->db->insert("users", $data);
        $data['id'] = $this
    }
}

My tests then look fairly nice and clearly show my intentions:

<?php

public function testItShouldOnlyReturnThoseOver18()
{
    $this->get('test.user_fixture_factory')->createUser(['date_of_birth' => '19 years ago']);
    $this->get('test.user_fixture_factory')->createUser(['date_of_birth' => '18 years ago']);
    $this->get('test.user_fixture_factory')->createUser(['date_of_birth' => '17 years ago']);

    $this->assertEquals(2, $this->object->getEligibleUsers());
}

Event then, I'm likely to extract the setup in to meaningful methods:

<?php

public function testItShouldOnlyReturnThoseOver18()
{
    $this->createEligbleUserInFixture();
    $this->createEligbleUserInFixture();
    $this->createIneligbleUserInFixture();

    $this->assertEquals(2, $this->object->getEligibleUsers());
}

I also use the same factories for gherkin tables in my behat tests, which look similar to your PSV

Given the following users exist:
    | Email               | Date of birth |
    | dave@example.com    | -18 years     |
    | bob@example.com     | -19 years     |
    | rob@example.com     | -17years       |

@malteriesch
Copy link
Contributor Author

@davedevelopment

Cheers for taking the time to have a look, it's really good getting feedback..!

I do like how you approach database testing.

To be sure, having intention-revealing method names is definitely the way to go, not only in test cases - I quite often find room for improvement on my projects to be sure.. Your name suggestion of shouldAllowMockingMethod for example I found a lot nicer than my original suggestion, and also quite a lot of the names I gave to methods in my psv project are quite unsatisfactory, I just haven't found better ones yet.. Frequent refactoring to the rescue, as always.

Clearly, good naming also aids one of the tests' purposes' of 'living' documentation. I do quite often put my PSV setups into parametrized methods, sometimes in helper classes, to aid in that, but your approach really does make it very nice and clear what is happening, having the factories separated out also should help with reusing them across tests.

I suppose that what I was looking for when I came up with my approach initially was the ability to 'dive in' really quickly into writing database tests to make them as easy to write as possible, also I like seeing in one glance in the test how the the SUT affects the database, especially when several tables are involved (although if there are too many tables, it gets complicated and that argument kind of goes out of the window, so an approach like yours is definitely more appropriate:)

Also, one could argue that the structure of the underlying database should be irrelevant, and for most classes that is surely true, but at the lowest level of abstraction I guess the database structure has some importance and it is nice to see how it relates to the classes under test. Again, this is really for the lowest level interaction only, any 'higher' classes should be db-agnostic, and should make use of mocks...

I guess at the end of the day it is one of many tools and approaches that can be employed an not necessarily the best one.

I saw the similarity of the Behat syntax to my 'psv' when I started using it last year and as quite amused to find that:)

Let me know if you want more help on Mockery...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants