Intereting Posts
PHP-переменная объекта чтения как часть другой переменной Html-форма размещения, данные не переданы Устранение неполадок «Ошибка разделителя не должна быть буквенно-цифровой или обратной косой чертой» при изменении ereg () на preg_match () покажите сообщение javascript перед продолжением PHP. Может ли автоматическая обработка каждой переменной $ _POST быть проблемой безопасности? Zend Framework 2 – Как использовать внешнюю библиотеку Как игнорировать определенные значения при применении json_encode к классу Получите пользователей новейших видео с YouTube? Выберите строки из таблицы MySQL, где value – массив? Зависимые тесты между двумя классами TestCase в PHPUnit do-while – самый быстрый цикл в php? Почему переменная не может начинаться с номера? Показывать второе раскрывающееся меню, основанное на предыдущем выпадающем списке. PHP – Как получить год, месяц, день из строки времени PHP – Как построить список древовидной структуры?

Издевательские модели Laravel Eloquent – как установить публичную собственность с помощью Mockery

Я хочу использовать mock-объект (Mockery) в моем тесте PHPUnit. Объект mock должен иметь как некоторые общедоступные методы, так и некоторые общедоступные свойства. Класс – это модель Laravel Eloquent. Я попробовал это:

$mock = Mockery::mock('User'); $mock->shouldReceive('hasRole')->once()->andReturn(true); //works fine $mock->roles = 2; //how to do this? currently returns an error $this->assertTrue(someTest($mock)); 

… но установка публичного свойства возвращает эту ошибку:

BadMethodCallException: метод Mockery_0_User :: setAttribute () не существует в этом макетном объекте

Эта ошибка не возвращается при издевательстве простого класса, но возвращается, когда я пытаюсь высмеять модель Eloquent. Что я делаю не так?

Related of "Издевательские модели Laravel Eloquent – как установить публичную собственность с помощью Mockery"

Если вы хотите получить это свойство с этим значением, просто используйте его:

 $mock ->shouldReceive('getAttribute') ->with('role') ->andReturn(2); 

Если вы вызываете $user->role вы получите – 2 ( $user – его класс mock User )

Этот ответ немного запоздал, но, надеюсь, это поможет кому-то. В настоящее время вы можете установить статическое свойство для издевающихся объектов Eloquent, используя ключевое слово 'alias':

 $mocked_model = Mockery::mock('alias:Namespace\For\Model'); $mocked_model->foo = 'bar'; $this->assertEquals('bar', $mocked_model->foo); 

Это также полезно для насмешек внешних классов поставщиков, таких как некоторые объекты Stripe.

Ознакомьтесь с ключевыми словами «псевдоним» и «перегрузка»: http://docs.mockery.io/en/latest/reference/startup_methods.html

Пробовал это? Он должен охватывать вас.

https://github.com/padraic/mockery/blob/master/docs/11-MOCKING-PUBLIC-PROPERTIES.md

Я бы сказал,

 protected $roles = array(); public function setRoles($roles) { $this->roles = $roles; } public function addRole($role) { $this->roles[] = $role; } 

Затем вы можете протестировать, используя:

 $mock = Mockery::mock('User'); $mock->shouldReceive('hasRole')->once()->andReturn(true); $mock->addRole(2); $this->assertTrue(someTest($mock)); 

Эта апсида дает вам возможность пообещать формат, когда вы используете getRoles (), который будет массивом объекта Role, если вы используете SOLID OOP, или если вы предпочитаете использовать массив, то, по крайней мере, вы знаете, что это всегда массив, который вы получаете.

Вы пытались делать частичные издевательства ? Вы можете попробовать что-то вроде (NOT TESTED):

 $mock = Mockery::mock('User[hasRole]'); $mock->shouldReceive('hasRole')->once()->andReturn(true); $mock->roles = 2; $this->assertTrue(someTest($mock)); 

Чтобы ответить на ваш вопрос, вы также можете попробовать что-то вроде этого:

 $mock = Mockery::mock('User'); $mock->shouldReceive('hasRole')->once()->andReturn(true); //works fine $mock->shouldReceive('setAttribute')->passthru(); $mock->roles = 2; $mock->shouldReceive('getAttribute')->passthru(); $this->assertEquals(2, $mock->roles); 

Или, как было предложено seblaze, используйте частичный макет:

 $mock = Mockery::mock('User[hasRole]'); $mock->shouldReceive('hasRole')->once()->andReturn(true); $mock->roles = 2; $this->assertEquals(2, $mock->roles); 

Но из вашего фрагмента кода, если вы пишете модульные тесты, вы должны сделать только одно утверждение за каждый тест:

 function test_someFunctionWhichCallsHasRole_CallsHasRole() { $mock = Mockery::mock('User'); $mock->shouldReceive('hasRole')->once(); $mock->someFunctionWhichCallsHasRole(); } function test_someFunctionWhichCallsHasRole_hasRoleReturnsTrue_ReturnsTrue() { $mock = Mockery::mock('User'); $mock->shouldReceive('hasRole')->once()->andReturn(true); $result = $mock->someFunctionWhichCallsHasRole(); $this->assertTrue($result); } 

Шпион – ваш друг по этому поводу:

 $mock = Mockery::spy('User'); $mock->shouldReceive('hasRole')->once()->andReturn(true); //works fine $mock->roles = 2; //how to do this? currently returns an error $this->assertTrue(someTest($mock)); 

вы можете использовать stdclass в этом случае.

 $obj = new stdClass(); $obj->roles = 2; $mock = Mockery::mock('User'); // return stdclass here. $mock->shouldReceive('hasRole')->once()->andReturn($obj); $mock->roles = 2; $this->assertEquals(2, $mock->roles);