PHPUnit 如何编写 Laravel Nova Observer 测试

PHPUnit how to write a Laravel Nova Observer test

我想为我的 CommentObserver 编写一个测试。该观察者只在 NovaServiceProvider 注册,不在 AppServiceProvider 注册。这意味着我无法使用我自己的控制器来测试我的观察者。

在我看来,我有3种方式来检验我的观察者:

  1. 通过向 Nova API
  2. 发送 post 请求来执行功能测试
  3. 通过调用观察者中的函数来模拟观察者,以检查函数是否按预期执行
  4. 尝试在 AppServiceProvider 中动态注册我的观察者,执行请求并再次在 AppServiceProvider 中注销观察者。

我试图为这 3 种方法中的任何一种找到解决方案来测试我的观察者,但不幸的是我失败了。

问题:

你们有关于我如何测试我的 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'
}