Laravel частично моделируемая модель не вызывается

я использую Ларавелла (4.2) рамки для разработки веб-приложений (PHP 5.4.25). Я создал интерфейс репозитория, который был реализован с помощью 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;
}
}
}

Моя реализация репозитория:

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;
}
}

Я также создал UsersControllerTest для тестирования контроллера, и все работает нормально, пользователь был добавлен в БД. После того, как я издевался 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());
}
}

Мой файл ruote:

Route::resource('users', 'UsersController');

Когда я запускаю тест, я получаю следующую ошибку:

Mockery\Exception\InvalidCountException : Method save() from Mockery_0_Gas_Storage_User_UserRepositoryInterface should be called
exactly 1 times but called 0 times.

Почему издеваются над методом спасти не называется?

Что случилось?


РЕДАКТИРОВАТЬ: без частичной имитации все работает нормально, теперь возникает вопрос: почему с частичной имитацией это не работает?


Спасибо

0

Решение

Оглядываясь назад на свой код, кажется, что вы должны иметь возможность использовать частичные имитации, просто изменив функцию mock на что-то вроде этого:

public function mock($class) {
$mock = Mockery::mock($class);
$ioc_binding = preg_replace('/\[.*\]/', '', $class);
$this->app->instance($ioc_binding, $mock);

return $mock;
}
2

Другие решения

Вы говорите издеваться, чтобы ожидать save() метод, но save() находится на модели Eloquent внутри репозитория, а не репозитория, над которым вы издеваетесь.

В вашем коде в настоящее время просачиваются детали реализации репозитория.

Вместо звонка:

$this->user->getUser()->username = Input::get('username');

Вам нужно передать экземпляр User в хранилище:

$this->user->add(User::create(Input::all());

Или вы передаете массив Input в хранилище и позволяют хранилищу создавать новые User экземпляр внутри:

$this->user->add(Input::all());

Вы бы тогда издевались add() метод в вашем тесте:

$this->mock->shouldReceive('add')->once();

Комментарии о том, что Laravel не подходит для насмешек или юнит-тестов, неверны.

1