Last active
March 1, 2020 07:14
-
-
Save JeffreyWay/4968363 to your computer and use it in GitHub Desktop.
To make for clean and readable tests, do your mocking in a base model that your Eloquent models extend.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class BaseModel extends Eloquent { | |
public static function shouldReceive() | |
{ | |
$repo = get_called_class() . 'RepositoryInterface'; | |
$mock = Mockery::mock($repo); | |
App::instance($repo, $mock); | |
return call_user_func_array(array($mock, 'shouldReceive'), func_get_args()); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class PostsTest extends TestCase { | |
public function testAllPosts() | |
{ | |
// This will mock the PostRepository interface, update the instance | |
// that will be injected into the controller (use DI), and stub the getAll method. | |
// This way, the DB will never be hit. | |
Post::shouldReceive('getAll')->andReturn('foo'); | |
// Call the route. | |
$response = $this->call('GET', 'posts'); | |
// Make sure that the request was successful. | |
$this->assertTrue($response->isOk()); | |
// also make sure that $posts is bound to the view | |
$this->assertEquals('foo', $response->getOriginalContent()->posts); | |
} | |
} |
@danharper in the framework tests, they extend the Eloquent class with a stub, to replace the newQuery method. IT is a bit convoluted, but it might work:
https://github.com/laravel/framework/blob/master/tests/Database/DatabaseEloquentModelTest.php
@karptonite Ah thanks, I'll give it a try! Only just noticed your reply, guess GitHub doesn't create notifications on mentions in Gists.
I had trouble using this snippet. I've found the problem to be namespaces. I thought I would share my modified code.
My repositories are in the Repositories namespace and models are in the Models namespace.
public static function shouldReceive($args)
{
$calledClassParts = explode('\\', get_called_class());
$calledClass = end($calledClassParts);
$repo = 'Repositories\\' . $calledClass . 'RepositoryInterface';
$mock = Mockery::mock($repo);
App::instance($repo, $mock);
return call_user_func_array([$mock, 'shouldReceive'], func_get_args());
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@danharper Just saw your question. My Repository tests also use sqlite in memory, rather than mocking the Foo. I get the same bug as you do when I try to mock Foo. I'm not certain, but I think that the problem is that all() is a static method.