2013-12-20 2 views
5

В настоящее время я пишу тесты для пакета в Laravel 4.Mocking обратных вызовов в Laravel 4 (издевательство)

Я насмешливый Illuminate\Database\Query\Builder, который работает почти все время, за исключением, когда метод where использует обратный вызов, я не могу проверьте, вызываются ли методы внутри обратного вызова.

Я надеялся, что один из вас может пролить некоторый свет.

$query = \Mockery::mock('Illuminate\Database\Query\Builder', function ($mock) { 
    /** @var \Mockery\Mock $mock */ 
    $mock->shouldReceive('where'); 
    $mock->shouldReceive('orWhere')->twice(); 
}); 

И фактический where метод, который должен вызвать orWhere. Примечание: Этот макет строителя переходит к классу ниже.

$builder = new LaravelBuilder($query); 

который затем вызывает $builder->filter() который содержит нижеследующий код.

$this->query->where(function ($query) use ($filterData) { 
    /** @var \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $query */ 
    foreach($filterData['columns'] as $colData) { 
     /** @var \Samvaughton\Ldt\Column $column */ 
     $column = $colData['column']; 

     // See if this column is searchable 
     if (!$column->isSearchable() || !$colData['searchable']) continue; 

     // If the individual column term is empty, use the main term 
     $term = (empty($colData['term'])) ? $filterData['term'] : $colData['term']; 

     // Actually apply the filter 
     $query->orWhere($column->getSqlColumn(), "LIKE", "%{$term}%"); 
    } 
}); 

Основная часть дна немного $query->orWhere, тесты PHPUnit неудачу каждый раз, когда он не запускается orWhere даже один раз. Прежде чем вы скажете, что это может не дойти до его выполнения из-за continue, данные, которые я передаю, позволят это.

Я подозреваю, что это связано с тем, как я издеваюсь над методом where. Если я добавлю exit до foreach, он не будет выполнен, показывая, что он даже не запускает ничего внутри обратного вызова. Я знаю, что это поведение по умолчанию, но как заставить Mockery запускать тот же/похожий обратный вызов?

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

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

ответ

3

ОК, поэтому я думаю, что это может быть сделано лучше, но я прибегал к частично издевательскому построению запросов Laravel.

См линии 324 в Illuminate\Database\Query\Builder

При использовании укупорочное Laravel порождает новый конструктор запросов, который также должен быть издевались. Вот код, который работал:

$query = \Mockery::mock('Illuminate\Database\Query\Builder', function ($mock) { 
    /** @var \Mockery\Mock $mock */ 
    $mock->makePartial(); 
    $mock->shouldReceive('where')->once()->passthru(); 
    $mock->shouldReceive('newQuery')->andReturn(
     \Mockery::mock('Illuminate\Database\Query\Builder', function ($mock) { 
      /** @var \Mockery\Mock $mock */ 
      $mock->makePartial(); 
      $mock->shouldReceive('orWhere')->twice(); 
     }) 
    ); 
}); 

мне нужно использовать makePartial() поэтому конструктор запросов сохранил свою первоначальную функциональность для закрытия (что не верно для модульного тестирования), так что это не самое лучшее решение. Отсюда я издеваюсь над методом newQuery, который вызывается для создания нового экземпляра построителя запросов, который затем издевается над тем же форматом.

+0

Это действительно помогло мне! Я не могу найти что-либо в документах Mockery о передаче закрытия в качестве второго аргумента 'mock'. Как вы это знаете? – alexw

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