2015-09-17 1 views
2

Я пишу модульные тесты для моего приложения laravel 5. В одном тесте я вызываю функцию и должен проверить, что в тестируемой функции вызывается статический метод create для другой модели.Как я могу издеваться над методом create на модели в laravel 5?

Я не хочу, чтобы на самом деле сохранялись любые ресурсы базы данных.

Я создал объект-макет, определенные ожидания и привязал его к экземпляру приложения, но когда create называется приложением, он пытается запустить SQL, а не перехватывать вызов функции макетным объектом.

public function testLogCreation() { 
    $this->log = Mockery::mock('App\Models\Log'); 
    $this->log->shouldReceive('create')->once(); 
    $this->app->instance('App\Models\Log',$this->log); 

    echo get_class($this->app['App\Models\Log']); // output: Mockery_2_App_Models_Log 
} 

There was 1 error

SQLSTATE[23503]: Foreign key violation: 7 ERROR: insert or update on table "logs" violates foreign key constraint....

Я также попытался $this->log->shouldReceive('save')->once();, так как я заметил, что статическая create функции вызывает функцию save общественности, но я думаю, что я не создаю макет ожидания на праве экземпляра log.

Если этого не может быть сделано, любые предложения по альтернативным стратегиям?

Спасибо!

ответ

1

Статические методы, как правило, трудно справиться с модульными испытаниями. Линия

$this->app->instance('App\Models\Log', $this->log); 

устанавливает свой макет в приложении для инъекции зависимостей, но инъекция зависимости только приходит в игру с объектами, созданных Laravel. Статические методы фактически не имеют базовый объект, поэтому он не применяется.

Один из подходов, который вы можете использовать, - это фабричный или служебный интерфейс, который имеет метод createLog. Этот интерфейс имеет конкретный класс, который создает модели Log с использованием статического метода (или, еще лучше, устраняет необходимость в статическом методе). Затем вы можете легко обмануть этот интерфейс в своих тестах и ​​подтвердить, что вызывается createLog.

Смотрите здесь для большого ответа на подобный вопрос: Laravel Dependency Injection: When do you have to? When can you mock Facades? Advantages of either method?

0

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

$log = $this->app->make('App\Models\Log')->fill($array); 
$log->save(); 

Это позволяет вам высмеять фактический объект вместо фасадного или статического метода. Затем вы можете использовать Mockery, как в вашем примере, только издеваться над методами «fill» и «save».

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