首页 > 解决方案 > 如何模拟自己未绑定在 laravel 容器中的类?

问题描述

我有一个简单的动作类,看起来像这样:

class Action
{
    public function execute()
    {
        $client = app(ApiClient::class);
        return $client->ambassadors();
     }
}

该类ApiClient未绑定到容器,该类也没有Action。它们只是我使用的常规课程。

现在在我的测试中,我想模拟它,ApiClient以便它不会对 API 进行实时调用。我尝试使用以下方法执行此操作:

public function test_that_it_returns_two_ambassadors(): void
{
    $action = app(Action::class);
    this->mock(ApiClient::class, function (MockInterface $mock) {
            $mock->shouldReceive('ambassadors')->once()
                ->andReturn([
                    ['id' => 1337, 'company' => 'Test store 1', 'email' => 'marcus@test.com'],
                    ['id' => 13371337, 'company' => 'Test store 2', 'email' => 'katja@test.com'],
                ]);
        });

    $action->execute();
}

无论我尝试什么,它仍然会进行实时通话,即我的 Mock 没有在我的测试中使用。我认为这与我的类可能不是来自容器有关。我试图将容器中的ApiClient和绑定Action到相同的结果。

有人知道我做错了什么吗?

标签: laravel

解决方案


你的问题应该很容易解决,你必须反转前两行代码,所以:

this->mock(ApiClient::class, function (MockInterface $mock) {
        $mock->shouldReceive('ambassadors')->once()
            ->andReturn([
                ['id' => 1337, 'company' => 'Test store 1', 'email' => 'marcus@test.com'],
                ['id' => 13371337, 'company' => 'Test store 2', 'email' => 'katja@test.com'],
            ]);
    });
$action = app(Action::class);

这是因为,您首先告诉 Container 您正在模拟ApiClient然后实例化Action,如果您反其道而行之,那么您也已经实例Action化了ApiClient


推荐阅读