使用 PHPUnit 进行 Laravel 模型模拟测试

问题描述 投票:0回答:1

我正在尝试模拟 PHPUnit 中的更新方法,但到目前为止

shouldReceive('update')
尚未被调用。

PostServiceTest.php

    public function test_can_update_a_post(): void
    {
        $mockedPostModel = Post::factory()->make();
        $mockedTitle = 'Updated Title';
        $mockedSlug = Str::slug($mockedTitle);
        $mockedPostData = ['title' => $mockedTitle, 'slug' => $mockedSlug];
        $updatedPostModel = Post::factory()->make($mockedPostData);
        \Log::info($mockedPostModel);
        \Log::info($updatedPostModel);

        $postMock = Mockery::mock(Post::class);
        $postMock->shouldReceive('findOrFail')->once()->with(1)->andReturn($mockedPostModel);
        $postMock->shouldReceive('update')->once()->with($mockedPostData)->andReturn($updatedPostModel);

        $postService = new AdminPostService($postMock);
        $post = $postService->findOrFail(1);
        \Log::info($post);
        $post->update($mockedPostData);
        \Log::info($post);

        // $this->assertInstanceOf(Post::class, $post);
        // $this->assertEquals($post->title, $mockedTitle);
        // $this->assertEquals($post->slug, $mockedSlug);
    }

日志

[2024-05-29 14:20:54] testing.INFO: {"title":"Otho Pfeffer","slug":"otho-pfeffer"}  
[2024-05-29 14:20:54] testing.INFO: {"title":"Updated Title","slug":"updated-title"}  
[2024-05-29 14:20:54] testing.INFO: {"title":"Otho Pfeffer","slug":"otho-pfeffer"}  
[2024-05-29 14:20:54] testing.INFO: {"title":"Otho Pfeffer","slug":"otho-pfeffer"}   

我的预期结果应该是日志的第四行应该与日志的第二行匹配,因为它是

$post->update($mockedPostData);

中的结果

执行

$result = $post->update($mockedPostData);
返回空/空白值

php laravel mocking phpunit
1个回答
0
投票

尝试以下操作:

public function test_can_update_a_post(): void
{
    $mockedPostModel = Post::factory()->make();
    $mockedTitle = 'Updated Title';
    $mockedSlug = Str::slug($mockedTitle);
    $mockedPostData = ['title' => $mockedTitle, 'slug' => $mockedSlug];
    $updatedPostModel = Post::factory()->make($mockedPostData);

    $postMock = Mockery::mock(Post::class);
    $postMock->shouldReceive('findOrFail')->once()->with(1)->andReturn($mockedPostModel);
    $postMock->shouldReceive('update')->once()->with($mockedPostData)->andReturn($updatedPostModel);

    $postService = new AdminPostService($postMock);
    $updatedPost = $postService->findOrFail(1);
    $updatedPost = $postService->update($mockedPostData); // use the same $postService for findById and update method

    $this->assertInstanceOf(Post::class, $updatedPost);
    $this->assertEquals($updatedPost->title, $updatedPostModel->title);
    $this->assertEquals($updatedPost->slug, $updatedPostModel->slug);
}

mocked模型是

$postMock
并用作
AdminPostService
中的参数,然后分配给
$postService
。这意味着所有模拟方法只能从
$postService
访问。将
$postService
的结果分配给变量并在断言中使用它。

© www.soinside.com 2019 - 2024. All rights reserved.