Я заметил, что мое тестирование PHPUnit выполнялось довольно медленно, почти около 8 секунд для каждого тестового примера, в котором участвовали GroupUsers
. Я начал отлаживать и обнаружил, что мой издевающийся статический класс все еще выполняется, и большая часть времени потребляется в слушателе для события, которое создается при создании GroupUser. Это событие получает список пользователей из базы данных, а затем отправляет соответствующее электронное письмо с использованием статического класса BrioMailer
, который я издеваюсь.Издевательские статические методы с mockery
У меня есть статический класс, который используется исключительно для отправки писем. У меня есть несколько методов в этом классе, которые изменят параметры шаблона и почты, а затем вызовут self::sendEmail
, чтобы отправить электронное письмо.
Я использую Laravel 5, и я не хочу, чтобы на самом деле были отправлены электронные письма, поэтому я включил режим притворения. Однако я заметил, что даже когда насмехается над классом, методы, вызываемые на него, все еще выполняются, я проверил это, введя код отладки в методе почтовой программы и выполнив мои модульные тесты.
Мой тест Case
public function testNotificationSentToMemberWhenNewGroupMediaIsSaved()
{
$brioMailer = \Mockery::mock('alias:BrioMailer');
$data = self::getRandomCommunityWithAssociatedData();
$community = $data['community'];
$admin = $data['admins'][0];
$firstUser = $data['users'][0];
$firstUser->created_by = $admin->id;
$secondUser = $data['users'][1];
$secondUser->created_by = $admin->id;
$notifications = $secondUser->notificationPreferences;
$notifications->{'new-media-member'} = 1;
$secondUser->notificationPreferences()->save($notifications);
$asset = factory(Asset\Video::class)->make();
$asset->community()->associate($community);
$asset->user()->associate($admin);
$asset->save();
$group = factory(Group::class)->make();
$group->community()->associate($community);
$group->created_by = $admin->id;
$group->save();
foreach([$firstUser, $secondUser, $admin] as $user) {
$groupUser = factory(GroupUser::class)->make();
$groupUser->user_id = $user->id;
$groupUser->group_id = $group->id;
$groupUser->created_by = $admin->id;
$groupUser->save();
}
$groupMedia = factory(GroupMedia::class)->make();
$groupMedia->asset()->associate($asset);
$groupMedia->user()->associate($firstUser);
$groupMedia->group()->associate($group);
$groupMedia->published_date = date('Y-m-d H:i:s', strtotime('-1 day'));
$this->assertTrue($groupMedia->save());
$brioMailer->shouldReceive('newMediaItemMember')->with($secondUser, $firstUser, $groupMedia);
}
Я проверил, что проблема в том, что слушатель событий принимает до 8 секунд для каждого пользователя, чтобы «делать вид», чтобы отправить по электронной почте. Хотя я издеваюсь над объектом, он по-прежнему выполняет статический метод.
Сначала я думал, что мне нужно добавить его в контейнер IoC для Laravel, но это всего лишь автозагруженный статический класс, который вызывается из разных частей приложения и не изначально хранится в IoC.
Следует отметить, что линия в нижней части тестового примера функционирует должным образом. Если я изменил порядок аргументов в методе shouldReceive() -> with(), тогда он начинает бросать ошибки.
Я просто в недоумении, почему вызов статического метода не ударяет по макету объекта, и именно поэтому он будет пытаться отправлять электронные письма вообще.
Будет оценена любая помощь или направление дальнейшего чтения.
Вам это не понравится, но правильным решением является исправление вашего дизайна, а не отправка электронной почты из статического вызова. Внесите надлежащий объект, ответственный за отправку электронной почты везде, где вам нужно это сделать, и высмеивать его в своих тестах. Боковое примечание: ваш тест полностью не читается. Подумайте об извлечении создания светильников (по крайней мере, к методу, но прочитайте о сборщиках тестовых данных и материнском объекте). –
Да, сегодня утром, если я должен использовать Провайдера или события со слушателем для отправки писем. Поиск статического класса очень громоздко для тестирования. Кроме того, это издеваются над тестовыми данными с использованием фабрик моделей и Faker, но мне еще нужно установить отношения для тестирования. Конечно, я мог бы извлечь это для другого метода, но тогда этот метод должен был бы вернуть массив объектов, которые были связаны друг с другом, и каждый тест отличается. –