在特征或模型中模拟依赖项注入

时间:2019-02-01 09:26:33

标签: laravel mocking phpunit

我正在尝试模拟依赖项注入或(最好是一种)模型关系。
模型PlacemorphTo关系,只有几个称为Placeable的模块。 模块/可放置位置可以detect靠近用户。其中之一是使用特定于模块的RemoteGateway

使用RemoteGateway的模型具有此方法

use UseRemote;
public function detect(Geolocalisable $geolocalisable): bool
{
    return $this->remote()->recognize($geolocalisable);
}

并使用此特征

trait UseRemote
{
    public static $remote;

    protected static function bootUseRemote()
    {
        self::$remote = app(RemoteGateway::class);
    }

    public function remote(): RemoteGateway
    {
        return self::$remote;
    }
}

当然,RemoteGateway已绑定

$this->app->bind(RemoteGateway::class, function ($app) {
    return new SomethingRemoteGateway();
});

由于remote()->recognize($user)依赖于外部服务,因此它通常总是返回false,但是对于我必须进行的测试,它会检测到他并且应该始终返回true。

我现在正在尝试模拟这种行为,但是它不起作用。

    /** @test */
    public function api_show_place_with_registrables: void
    {
        $user = factory(User::class)->create();

        // mocking Remote Gateway
        $remoteGateway = \Mockery::mock(RemoteGateway::class);
        $remoteGateway->shouldReceive('recognize')
            ->with($user)
            ->andReturn(true);
        $this->app->instance(RemoteGateway::class, $remoteGateway);


        $place = factory(Place::class)->create();

        $response = $this->actingAs($user, 'api')
            ->json('get', "/api/v1/places/{$place->id}");

        dd($response->getContent()); // <-- empty but when I hardcode true in SomethingRemoteGateway it's returning the values
    }

但是在使用Placeable时嘲笑true总是返回detect会更好。在这种情况下,我的测试将不依赖于模块的特异性之一。

我想到的另一种方法是创建一个FakePlaceable以便在我的工厂中使用(我将迭代所有已知的可放置模块并选择一个atm)

0 个答案:

没有答案