【发布时间】:2021-03-26 02:28:32
【问题描述】:
我有以下中间件来更新用户的 last_seen_at 字段,我只将它用于经过身份验证的用户可以调用它的路由:
// app/Http/Middleware/LastSeen.php
public function handle($request, Closure $next)
{
$user = $request->user();
$user->last_seen_at = now();
$user->save();
return $next($request);
}
// app/Http/Kernel.php
protected $routeMiddleware = [
// other middleware
'lastseen' => \App\Http\Middleware\LastSeen::class
]
// routes/api.php
Route::group([
'middleware' => ['jwt', 'lastseen']
], function () {
// routes
});
我为测试中间件编写了以下单元测试:
// tests/Unit/LastSeenMiddlewareTest.php
/** @test */
public function doesLastSeenMiddlewareUpdateUsersLastSeenAt()
{
$user = Mockery::mock(User::class);
$user->shouldReceive('setAttribute')->passthru();
$user->shouldReceive('save')->once();
$user = $user->makePartial();
app()->instance(User::class, $user);
$request = Mockery::mock(Request::class)
->shouldReceive('user')
->once()
->andReturn()
->getMock();
$middleware = new LastSeen;
$middleware->handle($request, function () {});
}
通过运行测试,我得到一个错误:ErrorException: Creating default object from empty value。但是,我不明白这个问题能够解决它。
【问题讨论】:
-
我将使用功能测试对其进行测试。基本上,在您的测试中创建一个分配了中间件的路由,访问该路由,在登录的用户上声明更新的
last_seen检查这篇文章laravel-news.com/testing-laravel-middleware -
@ml59 所以你说不可能进行单元测试?以前的开发人员为他们实现的大多数中间件编写了单元测试。我只是想保持一致。
-
我从不这么说。 Laravel 社区中有很多关于如何测试
Middleware、Request等的讨论。有些使用单元测试,有些使用功能测试。如果你想进行单元测试,你将不得不模拟很多东西,编写复杂的代码,可读性较差。我建议您进行功能测试,因为它更容易。在文章(上面的链接)中,您可以从框架的创建者那里找到有关实践单元与功能的更多信息 -
@ml59 呃,我发现了问题。这有点愚蠢。我自己发布了一个答案。这并不复杂。我想知道你对此的看法。我的测试可以吗?
标签: php laravel unit-testing mockery