mockingery-> shouldReceive (), проходящий, когда он не должен?

Я изучаю модульное тестирование в laravel, используя phpunit и насмешку. В настоящее время я пытаюсь проверить UsersController :: store ().

Я издеваюсь над моделью пользователя и использую его для тестирования метода индекса и, похоже, работает. Когда я вывожу $ this-> user-> all (), тест терпит неудачу и когда его в нем проходит.

При тестировании метода хранилища, хотя я использую макет, чтобы проверить, что модель пользователя получает validate () один раз. Метод хранилища пуст, но тест проходит. Я упустил ненужные части урока ради краткости

<?php class UsersController extends BaseController { public function __construct(User $user) { $this->user = $user; } /** * Display a listing of the resource. * * @return Response */ public function index() { $users = $this->user->all(); return View::make('users.index') ->with('users', $users); } /** * Show the form for creating a new resource. * * @return Response */ public function create() { return View::make('users.create'); } /** * Store a newly created resource in storage. * * @return Response */ public function store() { // } } 

UserControllerTest.php

 <?php use Mockery as m; class UserControllerTest extends TestCase { public function __construct() { $this->mock = m::mock('BaseModel', 'User'); } public function tearDown() { m::close(); } public function testIndex() { $this->mock ->shouldReceive('all') ->once() ->andReturn('All Users'); $this->app->instance('User', $this->mock); $this->call('GET', 'users'); $this->assertViewHas('users', 'All Users'); } public function testCreate() { View::shouldReceive('make')->once(); $this->call('GET', 'users/create'); $this->assertResponseOk(); } public function testStore() { $this->mock ->shouldReceive('validate') ->once() ->andReturn(m::mock(['passes' => 'true'])); $this->app->instance('User', $this->mock); $this->call('POST', 'users'); } } 

Вы не должны перезаписывать конструктор PHPUnit_Framework_TestCase , используйте setUp для целей инициализации. См. Также мой ответ на # 15051271, а также # 17504870

Mockery по умолчанию представляет собой библиотеку для обучения, а не издевательскую (что путает из-за ее имени).

Это означает, что ->shouldReceive(...) по умолчанию – «ноль или более раз». При использовании ->once() вы говорите, что его следует называть нулевым или однократным, но не более. Это означает, что он всегда пройдет.

Если вы хотите утверждать, что он вызывается один раз, вы можете использовать ->atLeast()->times(1) (один или несколько раз) или ->times(1) (ровно один раз)

Чтобы завершить ответ Wounter , вы должны вызвать Mockery::close() .

Этот статический вызов очищает контейнер Mockery, используемый текущим тестом, и запускает любые задачи проверки, необходимые для ваших ожиданий.

Этот ответ помог мне понять эту концепцию.