【发布时间】:2015-06-21 07:49:32
【问题描述】:
我在我的 Laravel 项目中使用 Mockery 来模拟 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.
这是UserController中activate()的内容:
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');
【问题讨论】:
-
我对 Mockery 还不是很了解,但我认为
where->first是不可能的,因为它不是一个有效的函数。在user对象上调用的函数/属性是where,它会返回一个你在上面调用first()的对象。 -
看看this question,看来我可以做到。
-
我在提供的问题中没有看到任何
..->shouldReceive('where->first')。只有存根答案有一些关于它的东西,但那是一个扩展或其他东西。 -
如果你不关心参数,你可以做 shouldReceive('select->where->runQuery->fetch')。 无论如何,分析代码我注意到了什么可能导致问题。可能是函数
first()实际上不是一个雄辩的模型函数这一事实导致了这个问题。 -
啊,谢谢,不知道链接是可能的。会试试看!
标签: unit-testing laravel mockery