2016-03-08 2 views
1

У меня есть следующий метод:Издевательства вернуть новый объект с andReturn

public function getThreads() 
{ 
    $results = \DB::select(\DB::raw(config('sql.messages.threads')), [$this->user->user_id]); 

    $messagesThreadsModel = app()->make(MessagesThreadsModel::class); 
    $messages = []; 

    foreach ($results as $r) { 
     $message = $messagesThreadsModel->find($r->messages_thread_id); 
     $message->unread = $r->unread; 
     $messages[] = $message; 
    } 

    return $messages; 
} 

Для проверки выше я издеваться вызовом \ DB :: выберите (через фасад Laravel), чтобы вернуть список объектов, как бы Обычно класс DB. Затем я загружаю модель потока сообщений, которая снова издевается и заменяется в контейнере (поэтому app() -> make() вернет свой посмеянный экземпляр, а не фактическую модель).

Наконец это:

$messagesThreadsModel->find($r->messages_thread_id); 

снова издевались вернуть фиктивный объект (окурок?). Все это выглядит следующим образом:

$threadsList = $this->mockThreads(); 

    // mock the raw expression, check the query 
    \DB::shouldReceive('raw')->once()->with(m::on(function($sql) 
    { 
     return strpos($sql, 'messages') !== false; 
    }))->andReturn(true); 

    // mock the DB call, return a list of objects 
    \DB::shouldReceive('select')->once()->with(true, [$this->usersModel->user_id, $this->usersModel->user_id, $this->usersModel->user_id])->andReturn($threadsList); 

    $mockThreadResult = new \StdClass; 
    $mockThreadResult->last = "date"; 

    $this->messagesThreadModel->makePartial(); 

    // HERE IS THE TRICKY PART! 
    $this->messagesThreadModel->shouldReceive('find')->times(count($threadsList))->andReturn($mockThreadResult); 

    $this->app->instance('App\Freemiom\Models\Messages\MessagesThreads', $this->messagesThreadModel); 

    $messages = new Messages($this->usersModel); 
    $threadList = $messages->getThreads(); 

В чем проблема? Поскольку я передаю уже созданный фиктивный объект, каждый раз в цикле, когда вызывается метод -> find, возвращается тот же объект.

Как мне посмеяться вернуть новый объект при каждом вызове? Возможно ли это? Или, может быть, я должен сделать рефакторинг кода, чтобы все это проверялось?

ответ

0

Таким образом, чтобы иметь возможность вернуть новый объект с каждым последовательным вызовом того же Передразнивал метод, я должен был использовать andReturnUsing так:

$this->messagesThreadModel->shouldReceive('find')->times(count($threadsList))->andReturnUsing(function() 
{ 
    $mockThreadResult = new \StdClass; 
    $mockThreadResult->last = "date"; 

    return $mockThreadResult; 
}); 

Это будет имитировать поведение модели красноречива, что также возвращает новый объект с помощью метода find().