I know you are not accepting fixture answers, but I could not figure it out either. The problem I was trying to solve actually was mocking some methods in model so to avoid creating underlying fixtures.
So I ended up using Proxy
pattern implementation in 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
...
}
In this example getPrice()
method from Product
model returns Product
price from related tables. And we mock it here so that we won't have to populate db with all related models fixtures. Nevertheless Product
itself is still a fixture.
Maybe not the best solution, but managed to save me some CPU time while keeping unit tests decoupled.
Docs here
http://docs.mockery.io/en/latest/reference/partial_mocks.html
update:
I also made a small helper to solve attribute proxying problem
/**
* @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;
}
This way all attributes and their corresponding values from original model become available in mock.
CustomerModel
instance which is not persistent in terms of ActiveRecord. At the same time you cannot mock id because somehow$customer->id = 123
won't assign value – Health