@asdasdqwe

Как создать mock в unit тестах laravel?

Есть обычный unit тест
<?php

namespace Tests\Unit\Listeners;

use App\Events\ApplicationSubmittedEvent;
use App\Listeners\NotifyEmployerListener;
use Mockery\MockInterface;
use PHPUnit\Framework\TestCase;

class NotifyEmployerListenerTest extends TestCase
{
    /**
     * A basic unit test example.
     *
     * @return void
     */
    public function test_handle()
    {
        $listener = new NotifyEmployerListener();

        $eventMock = $this->mock(ApplicationSubmittedEvent::class, function (MockInterface $mock) {
            $mock->employer = 'test evployer';

            $mock->shouldReceive('notify')->once();
        });

        $listener->handle($eventMock);
    }
}

Если вызвать $this->mock в unit тестах, получаем ошибку Call to undefined method Tests\Unit\Listeners\NotifyEmployerListenerTest::mock()

Зачем разработчики запретили создавать моки в unit, ведь именно в unit тестах чаще создаются моки, нежели во feature тестах
  • Вопрос задан
  • 74 просмотра
Решения вопроса 1
alexey-m-ukolov
@alexey-m-ukolov Куратор тега Laravel
Вы наследуете свой класс теста от PHPUnit и удивляетесь, что в нём нет методов Laravel.

P.S.
я хотел потестить listener отдельно unit тестом (проверить, что метод handle вызывается и никто его не удалил)
Здесь разумно сделать три теста:
  1. Что в вашем коде генерируется нужное событие в нужном месте. Проверяется только генерация, не смотрим, слушает ли кто-то это событие или нет.
  2. Что ваш EventServiceProvider настроен таким образом, что для этого события указан нужный слушатель. Здесь мы не смотрим, генерируется ли где-либо это событие и работает ли слушатель.
  3. Что ваш слушатель корректно работает, получив событие. Здесь вы просто руками вызываете его метод handle, передавая туда событие (как правило классы событий простые и их нет смысла мокать, проще создать нормально, но бывают и исключения) и проверяете его бизнес-логику.


Такой подход предполагает, что вы доверяете фреймворку и не тестируете логику его работы. Он теоретически может дать осечку или вы можете что-то сломать (например, выключить EventServiceProvider), но вероятность такого развития событий очень мала, зато такой подход очень сильно упрощает написание тестов.

P.P.S. Если у вас в событии есть метод notify, то вы что-то делаете неправильно. События - это DTO, в них не должно быть бизнес-логики.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы