Я использую Mockery в своем проекте Laravel, чтобы издеваться над моделью User Eloquent и тестировать маршрут.
Вот как я тестирую маршрут /api/user/activate
:
<?php
use Illuminate\Support\Facades\Session;
class ActivateTest extends TestCase
{
private $userMock;
public function setUp()
{
parent::setUp();
$this->userMock = Mockery::mock('App\User');
Session::start();
}
public function tearDown()
{
Mockery::close();
}
public function testActivate()
{
$this->userMock->shouldReceive('where->first')->once()->andReturn('test');
$this->userMock->shouldReceive('activate')->once();
$response = $this->call('POST', '/api/user/activate', [
'activationToken' => '838jfjnvu83u3',
'_token' => csrf_token()
]);
// This will be displayed in the PHPunit output
print_r($response->getContent());
$this->assertResponseStatus(200);
}
}
У меня проблема в том, что andReturn('test')
не работает. Результат PHPunit:
F{"error":{"message":null,"statusCode":404}}
Time: 276 ms, Memory: 15.50Mb
There was 1 failure:
1) ActivateTest::testActivate
Failed asserting that 404 matches expected 200.
Это содержимое activate()
в UserController
:
public function activate(Request $request)
{
$activation = $request->input();
$user = $this->user->where('activationToken', $activation['activationToken'])->first();
if(!$user) return $this->respondNotFound($user);
try
{
$user->activate($activation['password']);
}
catch(ModelException $e)
{
return $this->respondInternalError($e->errorMessages());
};
return $this->respondCreated('Account activated.');
}
Проблема в том, что $user
в контроллере равно null
, потому что макет не возвращает test
(в этом случае условие будет оцениваться как истинное, и я не получу ответ 404).
Изменить:
Я также пытался использовать насмешку PHPunit, но это не увенчалось успехом:
$this->userMock = $this->getMockBuilder('App\User')->setMethods(['where', 'first', 'activate'])->getMock();
$this->userMock->expects($this->once())->method('where')->willReturn($this->userMock);
$this->userMock->expects($this->once())->method('first')->willReturn('test');
$this->userMock->expects($this->once())->method('activate');
where->first
невозможен, потому что это недопустимая функция. Функция/атрибут, вызываемый для объектаuser
, — этоwhere
, и она возвращает объект, который вы вызываетеfirst()
на... - person Sven van Zoelen   schedule 15.04.2015..->shouldReceive('where->first')
в заданном вопросе. Только в заглушке есть что-то об этом, но это расширение или что-то в этом роде. - person Sven van Zoelen   schedule 15.04.2015first()
на самом деле не является функцией красноречивой модели. - person siannone   schedule 15.04.2015