Я пытаюсь смоделировать внедрение зависимости или (было бы лучше) модельное отношение.
Модель Place
как отношение morphTo
с несколькими модулями под названием 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
, но для тестов, которые я должен предположить, он обнаруживаетон и всегда должен возвращать истину.
Я сейчас пытаюсь высмеивать это поведение, но оно не работает.
/** @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 для использования на моих фабриках (я повторяю все известные модули placeablesи выберите один атм)