[英]Laravel partial mocked model not invoked
I'm using laravel (4.2) framework to develop a web application (PHP 5.4.25). 我正在使用laravel(4.2)框架来开发Web应用程序(PHP 5.4.25)。 I've create a repository-interface that was implemented with eloquent-repository, I use that repository inside a UserController:
我已经创建了一个用eloquent-repository实现的存储库接口,我在UserController中使用了该存储库:
# app/controllers/UsersController.php
use Gas\Storage\User\UserRepositoryInterface as User;
class UsersController extends \BaseController {
protected $user;
public function __construct(User $user) {
$this->user = $user;
}
public function store() {
$input = Input::all();
$validator = Validator::make(Input::all(), $this->user->getRoles());
if ( $validator->passes() ) {
$this->user->getUser()->username = Input::get('username');
$this->user->getUser()->password = Hash::make(Input::get('password'));
$this->user->getUser()->first_name = Input::get('first_name');
$this->user->getUser()->last_name = Input::get('last_name');
$this->user->getUser()->email = Input::get('email');
$this->user->save();
return false;
} else {
return true;
}
}
}
My Repository implementation: 我的存储库实现:
namespace Gas\Storage\User;
# app/lib/Gas/Storage/User/EloquentUserRepository.php
use User;
class EloquentUserRepository implements UserRepositoryInterface {
public $_eloquentUser;
public function __construct(User $user) {
$this->_eloquentUser = $user;
}
public function all()
{
return User::all();
}
public function find($id)
{
return User::find($id);
}
public function create($input)
{
return User::create($input);
}
public function save()
{
$this->_eloquentUser->save();
}
public function getRoles()
{
return User::$rules;
}
public function getUser()
{
return $this->_eloquentUser;
}
}
I've also create a UsersControllerTest to testing the controller and all works fine, the user was added to the DB. 我还创建了一个UsersControllerTest来测试控制器,并且一切正常,将用户添加到数据库中。 After I mocked my UserRepositoryInterface because I don't need to test the DB insert, but I just want to test the controller
在嘲笑UserRepositoryInterface之后,因为我不需要测试数据库插入,但是我只想测试控制器
class UsersControllerTest extends TestCase {
private $mock;
public function setUp() {
parent::setUp();
}
public function tearDown() {
Mockery::close();
}
public function mock($class) {
$mock = Mockery::mock($class);
$this->app->instance($class, $mock);
return $mock;
}
public function testStore() {
$this->mock = $this->mock('Gas\Storage\User\UserRepositoryInterface[save]');
$this->mock
->shouldReceive('save')
->once();
$data['username'] = 'xxxxxx';
$data['first_name'] = 'xxxx';
$data['last_name'] = 'xxxx';
$data['email'] = 'prova@gmail.com';
$data['password'] = 'password';
$data['password_confirmation'] = 'password';
$response = $this->call('POST', 'users', $data);
var_dump($response->getContent());
}
}
My ruote file: 我的ruote文件:
Route::resource('users', 'UsersController');
When I run the test I get the following error: 运行测试时,出现以下错误:
Mockery\Exception\InvalidCountException : Method save() from Mockery_0_Gas_Storage_User_UserRepositoryInterface should be called
exactly 1 times but called 0 times.
Why the mocked method save has not be called? 为什么没有调用模拟方法保存 ?
What is wrong? 怎么了?
EDIT: without partial mock all works fine, now the question is: why with partial mock it doesn't work? 编辑:没有部分模拟都可以正常工作,现在的问题是:为什么部分模拟不起作用?
Thanks 谢谢
Looking back at your code, it seems like you should be able to use partial mocks just by changing your mock function to something like this: 回顾一下代码,似乎只需将模拟函数更改为以下内容即可使用部分模拟:
public function mock($class) {
$mock = Mockery::mock($class);
$ioc_binding = preg_replace('/\[.*\]/', '', $class);
$this->app->instance($ioc_binding, $mock);
return $mock;
}
You are telling the mock to expect the save()
method, but the save()
is on the Eloquent model inside the Repository, not the Repository you are mocking. 您告诉模拟对象期望使用
save()
方法,但是save()
位于存储库内的Eloquent模型上,而不是您要模拟的存储库上。
Your code is currently leaking details of the implementation of the Repository. 您的代码当前正在泄漏存储库实现的详细信息。
Instead of calling: 而不是调用:
$this->user->getUser()->username = Input::get('username');
You need to pass an instance of the User
into the Repository: 您需要将
User
的实例传递到存储库中:
$this->user->add(User::create(Input::all());
Or you pass the array of Input
into the Repository and allow the Repository to create a new User
instance internally: 或者,您将
Input
数组传递到存储库中,并允许存储库在内部创建一个新的User
实例:
$this->user->add(Input::all());
You would then mock the add()
method in your test: 然后,您可以在测试中模拟
add()
方法:
$this->mock->shouldReceive('add')->once();
The comments about Laravel not being suited for mocking or unit testing are wrong. 关于Laravel不适合模拟或单元测试的评论是错误的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.