PHPUnit 如何编写 Laravel Nova Observer 测试
PHPUnit how to write a Laravel Nova Observer test
我想为我的 CommentObserver 编写一个测试。该观察者只在 NovaServiceProvider 注册,不在 AppServiceProvider 注册。这意味着我无法使用我自己的控制器来测试我的观察者。
在我看来,我有3种方式来检验我的观察者:
- 通过向 Nova API
发送 post 请求来执行功能测试
- 通过调用观察者中的函数来模拟观察者,以检查函数是否按预期执行
- 尝试在 AppServiceProvider 中动态注册我的观察者,执行请求并再次在 AppServiceProvider 中注销观察者。
我试图为这 3 种方法中的任何一种找到解决方案来测试我的观察者,但不幸的是我失败了。
问题:
- 对于方法 1,我总是收到验证错误,Nova 告诉我输入无效。
- 对于方法 2,我无法模拟观察者函数
- 对于方法 3,我没有找到任何关于如何在 AppServiceProvider 上动态注册和注销 oberserver 的解决方案
你们有关于我如何测试我的 CommentObserver 的想法和解决方案吗(如上所述,它只在我的 NovaServiceProvider 中注册)。
更新:
所以,这是我的观察者的代码。我需要有一个有效的请求来测试我的观察者,以便能够访问 $request->input('images')
变量。我知道我也可以使用 $comment->content
而不是 request()->input('content')
因为 $comment->content
已经包含了此时没有保存的新内容。
我需要有效请求的原因是变量 images
不是 Comment
模型的一部分。所以我不能使用 $comment->images
因为它根本不存在。这就是为什么我需要访问请求输入。我的观察者基本上做的是从内容中提取 base64
图像,将它们保存到服务器并用图像替换它们 link.
class CommentObserver
{
public function updating(Comment $comment)
{
if (!request()->input('content')) {
return;
}
if (request()->input('content') == $comment->getRawOriginal('content')) {
return;
}
$images = request()->input('images');
if(!is_array($images)) {
$images = json_decode(request()->input('images'));
}
checkExistingImagesAndDeleteWhenNotFound($comment, request()->input('content'), 'comments', 'medium');
$comment->content = addBase64ImagesToModelFromContent($comment, request()->input('content'), $images, 'comments', 'medium');
}
}
这是我到目前为止的测试。我选择方式 1,但正如已经描述的那样,这总是导致 nova 控制器出现验证错误,我无法弄清楚 error/what 丢失或错误的原因。
class CommentObserverTest extends TestCase
{
/** @test */
public function it_test()
{
$user = User::factory()->create([
'role_id' => Role::getIdByName('admin')
]);
$product = Product::factory()->create();
$comment = Comment::factory()->create(['user_id' => $user->id, 'content' => '<p>Das ist wirklich ein super Preis!</p>', 'commentable_type' => 'App\Models\Product', 'commentable_id' => $product->id]);
$data = [
'content' => '<p>Das ist wirklich ein HAMMER Preis!</p>',
'contentDraftId' => '278350e2-1b6b-4009-b4a5-05b92aedaae6',
'pageStatus' => PageStatus::getIdByStatus('publish'),
'pageStatus_trashed' => false,
'commentable' => $product->id,
'commentable_type' => 'App\Models\Product',
'commentable_trashed' => false,
'user' => $user->id,
'user_trashed' => false,
'_method' => 'PUT',
'_retrieved_at' => now()
];
$this->actingAs($user);
$response = $this->put('http://nova.mywebsiteproject.test/nova-api/comments/' . $comment->id, $data);
dd($response->decodeResponseJson());
$das = new CommentObserver();
}
}
谨致问候,谢谢
为什么要依赖 NovaServiceProvider
中的引导方法?可以在测试中即时调用 observe()
方法:
class ExampleTest extends TestCase
{
/** @test */
public function observe_test()
{
Model::observe(ModelObserver::class);
// If you need the request helper, you can add input like so:
request()->merge([
'content' => 'test'
]);
// Fire model event by updating model
$model->update([
'someField' => 'someValue',
]);
// Updating should be triggered in ModelObserver
}
}
你的观察者现在应该可以了 class:
public function updating(Model $model)
{
dd(request()->input('content')); // returns 'test'
}
我想为我的 CommentObserver 编写一个测试。该观察者只在 NovaServiceProvider 注册,不在 AppServiceProvider 注册。这意味着我无法使用我自己的控制器来测试我的观察者。
在我看来,我有3种方式来检验我的观察者:
- 通过向 Nova API 发送 post 请求来执行功能测试
- 通过调用观察者中的函数来模拟观察者,以检查函数是否按预期执行
- 尝试在 AppServiceProvider 中动态注册我的观察者,执行请求并再次在 AppServiceProvider 中注销观察者。
我试图为这 3 种方法中的任何一种找到解决方案来测试我的观察者,但不幸的是我失败了。
问题:
- 对于方法 1,我总是收到验证错误,Nova 告诉我输入无效。
- 对于方法 2,我无法模拟观察者函数
- 对于方法 3,我没有找到任何关于如何在 AppServiceProvider 上动态注册和注销 oberserver 的解决方案
你们有关于我如何测试我的 CommentObserver 的想法和解决方案吗(如上所述,它只在我的 NovaServiceProvider 中注册)。
更新:
所以,这是我的观察者的代码。我需要有一个有效的请求来测试我的观察者,以便能够访问 $request->input('images')
变量。我知道我也可以使用 $comment->content
而不是 request()->input('content')
因为 $comment->content
已经包含了此时没有保存的新内容。
我需要有效请求的原因是变量 images
不是 Comment
模型的一部分。所以我不能使用 $comment->images
因为它根本不存在。这就是为什么我需要访问请求输入。我的观察者基本上做的是从内容中提取 base64
图像,将它们保存到服务器并用图像替换它们 link.
class CommentObserver
{
public function updating(Comment $comment)
{
if (!request()->input('content')) {
return;
}
if (request()->input('content') == $comment->getRawOriginal('content')) {
return;
}
$images = request()->input('images');
if(!is_array($images)) {
$images = json_decode(request()->input('images'));
}
checkExistingImagesAndDeleteWhenNotFound($comment, request()->input('content'), 'comments', 'medium');
$comment->content = addBase64ImagesToModelFromContent($comment, request()->input('content'), $images, 'comments', 'medium');
}
}
这是我到目前为止的测试。我选择方式 1,但正如已经描述的那样,这总是导致 nova 控制器出现验证错误,我无法弄清楚 error/what 丢失或错误的原因。
class CommentObserverTest extends TestCase
{
/** @test */
public function it_test()
{
$user = User::factory()->create([
'role_id' => Role::getIdByName('admin')
]);
$product = Product::factory()->create();
$comment = Comment::factory()->create(['user_id' => $user->id, 'content' => '<p>Das ist wirklich ein super Preis!</p>', 'commentable_type' => 'App\Models\Product', 'commentable_id' => $product->id]);
$data = [
'content' => '<p>Das ist wirklich ein HAMMER Preis!</p>',
'contentDraftId' => '278350e2-1b6b-4009-b4a5-05b92aedaae6',
'pageStatus' => PageStatus::getIdByStatus('publish'),
'pageStatus_trashed' => false,
'commentable' => $product->id,
'commentable_type' => 'App\Models\Product',
'commentable_trashed' => false,
'user' => $user->id,
'user_trashed' => false,
'_method' => 'PUT',
'_retrieved_at' => now()
];
$this->actingAs($user);
$response = $this->put('http://nova.mywebsiteproject.test/nova-api/comments/' . $comment->id, $data);
dd($response->decodeResponseJson());
$das = new CommentObserver();
}
}
谨致问候,谢谢
为什么要依赖 NovaServiceProvider
中的引导方法?可以在测试中即时调用 observe()
方法:
class ExampleTest extends TestCase
{
/** @test */
public function observe_test()
{
Model::observe(ModelObserver::class);
// If you need the request helper, you can add input like so:
request()->merge([
'content' => 'test'
]);
// Fire model event by updating model
$model->update([
'someField' => 'someValue',
]);
// Updating should be triggered in ModelObserver
}
}
你的观察者现在应该可以了 class:
public function updating(Model $model)
{
dd(request()->input('content')); // returns 'test'
}