2014-09-14 13 views
0

Я использую laravel (4.2) framework для разработки веб-приложения (PHP 5.4.25). Я создать хранилище интерфейс, который был реализован с красноречивым-хранилище, я использую это хранилище внутри UserController:Laravel частично издевательская модель не вызывается

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

Моя Repository реализация:

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, потому что мне не нужно, чтобы проверить DB вставку, но я просто хочу, чтобы проверить контроллер

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'] = '[email protected]'; 
     $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. 

Почему меня дразнил thod сохранить не назовем?

Что не так?


EDIT: без частичного издеваться все работает отлично, теперь вопрос: почему с частичной издеваться он не работает?


Благодаря

+0

Похоже, пространство имен класса вы издевательским является по-разному в методе метода «mock» из того, что вы получили в своем «использовании» на вашем контроллере. Один начинается с «Газа», а другой начинается с «Пути». – patricksayshi

+0

@patricksayshi это моя ошибка, которую я сделал, когда писал вопрос – PapaSmurf

+0

laravel не подходит для издевательств в контексте модульного тестирования. так почему вы пытаетесь? (не то, что это попадает в неправильный инструмент для категории работы) – hakre

ответ

2

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

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

    return $mock; 
} 
+0

Я реализовал вашу функцию mock в своем коде, но когда я запустил тест, я получил следующую ошибку: «BadMethodCallException: метод Mockery_0_Gas_Storage_User_UserRepositoryInterface :: getRoles() не существует в этом макетном объекте». Кажется, что частичный макет не работает, но он ожидал, что все методы объекта издеваются. – PapaSmurf

+1

Ну, по крайней мере, вы знаете, что теперь ваш макет передается на тест. «Похоже, что ... он ожидал, что все методы объекта издеваются» - это точно. Вам нужно использовать «shouldReceive()», чтобы сообщить макет, что делать для каждого метода *, который будет вызываться на нем. Да, это серьезная боль в заднице. Вы напишете лучший/более простой код в долгосрочной перспективе, если вы разработаете свои классы с учетом этого. Например, функция 'save()' вашего repo может принимать * все * входные данные и передавать их в модель. Тогда ваш UserController не должен знать вообще о модели – patricksayshi

+0

Мне бы понравилась отдельная бизнес-логика и dao (объект доступа к данным), поэтому я поместил свой входной валидационный код внутри контроллера. – PapaSmurf

1

Вы сообщаете издеваться ожидать метод save(), но save() на модели красноречивый внутри Repository, не Repository вы насмешливый.

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

Вместо вызова:

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

Вам необходимо пройти экземпляр User в Repository:

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

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

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

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

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

Комментарии о Laravel не будучи подходят для насмешливых или модульного тестирования являются неправильными.

+0

Я пытался сделать то, что вы сказали, вместо этого вызывается 'save()', я вызываю 'create (Input :: all())', но результат тот же, мой издевающийся вызов игнорируется. Я добавляю мою реализацию Репозитория к моему вопросу. – PapaSmurf

+0

Без частичного макета '$ this-> mock = $ this-> mock ('Gas \ Storage \ User \ UserRepositoryInterface');' отлично работает, но с '$ this-> mock = $ this-> mock ('Gas \ Хранение \ Пользователь \ UserRepositoryInterface [save] '); 'он не работает. Зачем? – PapaSmurf

 Смежные вопросы

  • Нет связанных вопросов^_^