-
Notifications
You must be signed in to change notification settings - Fork 462
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
added shouldAllowMockingMethod method to allow non-existing methods to b... #296
Conversation
…o be mocked, useful for magic methods
…ods-for-mocking added shouldAllowMockingMethod method to allow non-existing methods to b...
Thanks! |
@davedevelopment @padraic 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: 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... 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... |
@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 |
|
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... |
updated pull request for #173