Как издеваться над результатом класса-оболочки API в PHPUNIT? - PullRequest
0 голосов
/ 03 августа 2020

Я использую пакет календаря spat ie laravel для выполнения вызовов API в Google Calendar Я хочу написать несколько тестов функций, но хочу имитировать класс оболочки событий, чтобы мои тесты фактически не вызывали API

Я использовал фасады Laravels для

Controller

class CalendarEventController extends Controller
{
    public function show($calendarId, $event_id)
    {
        return response()->json(\Facades\Event::find($event_id, $calendarId));
    }
}

метод Event:find возвращает сам себя. Большая часть данных содержится в параметре googleEvent.

Класс события

class Event
{
    /** @var \Google_Service_Calendar_Event */
    public $googleEvent;

}

Тест

public function test_event(){
    
        \Facades\Event::shouldReceive('find')->once()->andReturn(?);
        $response = $this->json('GET','/event/1/1');
        $response->assertJson([
        ...
        ]);
}

Что хочу ли я, чтобы этот Mocked Facade возвращался, чтобы получить ответ в ожидаемом формате.

Я решил, что могу вернуть новый экземпляр Event, но у класса события есть куча зависимостей, которые мне понадобятся макет

Если я возвращаю Self, он возвращает макет объекта, но googleEvent имеет значение null.

Edit

, потому что я никогда не устанавливал событие google. Таким образом, один из возможных вариантов -

$mock = \Facades\Event::shouldReceive('find')->once()->andReturnSelf()->getMock();
$mock->googleEvent = {Whatever}

, но это все еще оставляет проблему, когда мне нужно издеваться над 5 классами, чтобы получить правильный формат результата End Edit

Что должно Я делаю имитацию этого класса, чтобы получить данные обратно в том формате, в котором они были бы, если бы это был обычный запрос?

Формат результата выглядит следующим образом

  +googleEvent: Google_Service_Calendar_Event    
    +id: "XXX"
    +kind: "calendar#event"
    ...
    ...
    +"creator": Google_Service_Calendar_EventCreator 
    +"organizer": Google_Service_Calendar_EventOrganizer 
    +"start": Google_Service_Calendar_EventDateTime 
    +"end": Google_Service_Calendar_EventDateTime 
    +"reminders": Google_Service_Calendar_EventReminders

В для того, чтобы имитировать это, потребуется имитировать Google_Service_Calendar_Event, который требует других 5 классов GOOGLE_SERVICE_CALENDAR_ * и т. д.

1 Ответ

0 голосов
/ 05 августа 2020

Используя предложения @KurtFrais, я нашел решение.

Он предложил заменить реализацию на фиктивный объект, основанный на окружении. Вместо изменения реализации в ServiceProvider я изменил реализацию в тестовом методе.

Я создал фиктивный объект

class EventMock extends Event{

    public $googleEvent;

    public static function find($eventId, string $calendarId = null): Event
    {
        $self = new self();
        $self->googleEvent = $self->fake();
        return $self;
    }


    ...
    ...
}

Затем в тестовом методе я поменял реализацию вот так

public function test_event()
{
    $this->instance(Event::class,new EventMock());


    $response = $this->json('GET','/event/1/1');
    $response->assertJson([
    ...
    ]);
}

Поэтому, когда Laravel получает новый экземпляр класса событий, вместо него используется объект EventMock.

...