2016-03-21 6 views
0

Я заметил, что мое тестирование 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(), тогда он начинает бросать ошибки.

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

Будет оценена любая помощь или направление дальнейшего чтения.

+1

Вам это не понравится, но правильным решением является исправление вашего дизайна, а не отправка электронной почты из статического вызова. Внесите надлежащий объект, ответственный за отправку электронной почты везде, где вам нужно это сделать, и высмеивать его в своих тестах. Боковое примечание: ваш тест полностью не читается. Подумайте об извлечении создания светильников (по крайней мере, к методу, но прочитайте о сборщиках тестовых данных и материнском объекте). –

+0

Да, сегодня утром, если я должен использовать Провайдера или события со слушателем для отправки писем. Поиск статического класса очень громоздко для тестирования. Кроме того, это издеваются над тестовыми данными с использованием фабрик моделей и Faker, но мне еще нужно установить отношения для тестирования. Конечно, я мог бы извлечь это для другого метода, но тогда этот метод должен был бы вернуть массив объектов, которые были связаны друг с другом, и каждый тест отличается. –

ответ

-2

Использовать фасады вместо статических методов.

В наши дни легко издеваться над фасадами. У них есть документация.

https://laravel.com/docs/5.3/mocking#mocking-facades

Хорошо, если вам не нравятся фасады. Попробуйте одиночные игры.

+0

и почему у меня есть 2 минута? –

Смежные вопросы