Я запускаю phpunit с насмешкой (без БД/фикстур), но у меня проблемы с насмешкой над моделью.
$customer = Mockery::mock(CustomerModel::class);
echo $customer->id;
Выдает ошибку:
BadMethodCallException: Method Mockery_1_models_Customer::hasAttribute() does not exist on this mock object
Потом попробовал:
$customer->shouldReceive('hasAttribute')->andReturn(true);
Но снова я натыкаюсь на:
Fatal error: Call to a member function getDb() on a non-object in ..\yiisoft\yii2\db\ActiveRecord.php on line 135
Какие-либо предложения?
2 ответа
Я знаю, что вы не принимаете ответы на приспособления, но я тоже не мог этого понять. Проблема, которую я пытался решить, на самом деле заключалась в том, чтобы имитировать некоторые методы в модели, чтобы избежать создания базовых фикстур.
В итоге я использовал реализацию шаблона Proxy
в Mockery.
private $_product;
public function testMe()
{
// Here we use fixtured instance of Product model to build a Proxy
$this->_product = \Mockery::mock($this->product('product1'));
// somehow model attributes are inaccessible via proxy, but we can set them directly as a Proxy property
$this->_product->id = 1;
$this->_product->shouldReceive('getPrice')->andReturn(1000);
// assertions below
...
}
В этом примере метод getPrice()
из модели Product
возвращает цену Product
из связанных таблиц. И мы издеваемся над этим здесь, чтобы нам не пришлось заполнять БД всеми связанными моделями фикстур. Тем не менее Product
сам по себе по-прежнему является приспособлением.
Возможно, это не лучшее решение, но мне удалось сэкономить немного процессорного времени, сохраняя развязку модульных тестов.
Документы здесь http://docs.mockery.io/en/latest/reference/partial_mocks.html
обновить :
Я также сделал небольшой помощник для решения проблемы с проксированием атрибутов.
/**
* @param \yii\base\Model $model
* @return \Mockery\MockInterface
*/
private function setupMock($model)
{
$mock = \Mockery::mock($model);
foreach ($model->getAttributes() as $key => $value) {
$mock->$key = $value;
}
return $mock;
}
Таким образом, все атрибуты и соответствующие им значения из исходной модели становятся доступны в макете.
Является ли традиционным частичным макетом или Пассивный частичный макет что вы ищете?
$customer = Mockery::mock(CustomerModel::className())->makePartial();
echo $customer->id;
Приведенный выше пример, конечно, ничего не вернет, поскольку id не установлен, но не выдаст никаких ошибок.
CustomerModel
, который не является постоянным с точки зрения ActiveRecord. В то же время вы не можете имитировать идентификатор, потому что $customer->id = 123
почему-то не будет присваивать значение
Похожие вопросы
Новые вопросы
unit-testing
Модульное тестирование - это метод, с помощью которого отдельные блоки исходного кода тестируются, чтобы определить, пригодны ли они для использования.