2013-12-20 2 views
2

Проблема в том, что я не могу проверить одну функцию, потому что она касается других функций одного и того же репозитория.Тестирование репозитория laravel, у которого есть модель как зависимость

  1. Нужно ли проверять одну функцию в изоляции от других функций в том же репозитории, или нормально, что одна функция может обращаться к другим функциям в том же хранилище?
  2. Если функция должна быть проверена изолированно от других, как это можно сделать, потому что я не понимаю, как я могу издеваться над репозиторием, в котором я работаю. Я понимаю, как издеваться над зависимостями, но как издеваться над другими функциями в том же репозитории?
  3. Я правильно ли разбираюсь с моделью в методе setUp в тесте?

Код:

Реальный мир связыванию и хранилища:

// Bind User repository interface 
$app->bind('MyApp\Repositories\User\UserInterface', function() { 
    return new EloquentUser(new User); 
}); 

EloquentUser.php:

public function __construct(Model $user) 
{ 
    $this->user = $user; 
} 

public function findById($id) 
{ 
    return $this->user->find($id); 
} 

public function replace($data) 
{ 
    $user = $this->findById($data['user']['id']); 

    // If user not exists, create new one with defined values. 
    if (! $user) { 
     return $this->create($data); 
    } else { 
     return $this->update($data); 
    } 
} 

public function create($data) 
{ 
    $user = $this->user->create($data['user']); 

    if ($user) { 

     return $this->createProfile($user, $data['profile']); 

    } else { 

     return false; 
    } 
} 

private function createProfile($user, $profile) 
{ 
    return $user->profile()->create($profile); 
} 

public function update($user, $data) 
{ 
    foreach ($data['user'] as $key => $value) { 
     $user->{$key} = $value; 
    } 

    if (isset($data['profile']) && count($data['profile']) > 0) { 

     foreach ($data['profile'] as $key => $value) { 
      $user->profile->$key = $value; 
     } 
    } 

    return ($user->push()) ? $user : false; 
} 

EloquentUserTest.php

public function setUp() 
{ 
    parent::setUp(); 
    $this->user = Mockery::mock('Illuminate\Database\Eloquent\Model', 'MyApp\Models\User\User'); 
    App::instance('MyApp\Models\User\User', $this->user); 
    $this->repository = new EloquentUser($this->user); 
} 

public function testReplaceCallsCreateMethod() 
{ 
    $data = [ 
     'user' => [ 
      'id' => 1, 
      'email' => '[email protected]', 
     ], 
     'profile' => [ 
      'name' => 'John Doe', 
      'image' => 'abcdef.png', 
     ], 
    ]; 

    // Mock the "find" call that is made in findById() 
    $this->user->shouldReceive('find')->once()->andReturn(false); 

    // Mock the "create" call that is made in create() method 
    $this->user->shouldReceive('create')->once()->andReturn(true); 

    // Run replace method that i want to test 
    $result = $this->repository->replace($data); 

    $this->assertInstanceOf('Illuminate\Database\Eloquent\Model', $result, 'Should be an instance of Illuminate\Database\Eloquent\Model'); 
} 

При выполнении этого теста я получил:

Fatal error: Call to a member function profile() on a non-object in C:\Htdocs\at.univemba.com\uv2\app\logic\Univemba\Repositories\User\EloquentUser.php on line 107 

Так это означает, что тест пытается потрогать функцию в EloquentUser.php:

private function createProfile($user, $profile) 
{ 
    return $user->profile()->create($profile); 
} 

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

ответ

7

Вопрос решен. Просто нужно было создать еще один экземпляр модели и передать его в издеваемом методе.

Мой рабочий метод установки:

public function setUp() 
{ 
    parent::setUp(); 

    $this->user = Mockery::mock('MyApp\Models\User\User'); 

    App::instance('MyApp\Models\User\User', $this->user); 

    $this->repository = new EloquentUser($this->user); 
} 

Работа Метод испытания:

public function testReplaceCallsCreateMethod() 
{ 
    $data = [ 
     'user' => [ 
      'id' => 1, 
      'email' => '[email protected]', 
      'password' => 'plain', 
     ], 
     'profile' => [ 
      'name' => 'John Doe', 
      'image' => 'abcdef.png', 
     ], 
    ]; 

    // Mock Model's find method 
    $this->user->shouldReceive('find')->once()->andReturn(false); 

    // Create new Model instance 
    $mockedUser = Mockery::mock('MyApp\Models\User\User'); 

    // Mock Models profile->create and pass Model as a result of a function 
    $mockedUser->shouldReceive('profile->create')->with($data['profile'])->andReturn($mockedUser); 

    // Pass second instance Model as a result 
    $this->user->shouldReceive('create')->once()->andReturn($mockedUser); 

    // Now all $user->profile is properly mocked and will return correct data 
    $result = $this->repository->replace($data); 

    $this->assertInstanceOf('Illuminate\Database\Eloquent\Model', $result, 'Should be an instance of Illuminate\Database\Eloquent\Model'); 
} 
Смежные вопросы