2015-07-03 25 views
6

Ben alay ile phpunit (DB/fikstür olmadan) çalıştırıyorum, ama bir model alay ile ilgili bir sorunum var. Denedim SonraYii2 Mockery ile ActiveRecord ile alay etme

BadMethodCallException: Method Mockery_1_models_Customer::hasAttribute() does not exist on this mock object

:

$customer->shouldReceive('hasAttribute')->andReturn(true); 

Ama yine, ben de çalıştırın:

$customer = Mockery::mock(CustomerModel::class); 
echo $customer->id; 

hata üretir

Fatal error: Call to a member function getDb() on a non-object in ..\yiisoft\yii2\db\ActiveRecord.php on line 135

Herhangi bir öneriniz var mı?

cevap

2

Fikstür yanıtlarını kabul etmediğinizi biliyorum, ancak bunu da anlayamadım. Çözmeyi denediğim problem, aslında altta yatan fikstürlerin yaratılmaması için modeldeki bazı yöntemlerle alay ediyordu.

yüzden Product modeli ilişkili tablolardan Product fiyatını getirir bu örnek getPrice() yöntemde

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 
    ... 
} 

alay

yılında Proxy desen uygulamasını kullanarak sona erdi. Ve biz burada alay ediyoruz, böylece tüm ilgili model armatürleri ile db doldurmak zorunda kalmayacağız. Yine de Product'un kendisi hala bir armatürdür.

Belki de en iyi çözüm değil, ancak birim testleri ayrıştırılırken bana biraz işlemci zaman kazandırdı. Burada

Dokümanlar http://docs.mockery.io/en/latest/reference/partial_mocks.html

güncelleme:

Ben de sorunu

/** 
* @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; 
} 

orijinal modelden tüm nitelikleri ve bunlara karşılık gelen değerler haline Bu şekilde proxy özelliği çözmek için küçük bir yardımcı yapılmış sahte olarak kullanılabilir.

+0

Teşekkürler, deneyeceğim! –

1

Traditional Partial Mock veya Passive Partial Mock Ne arıyorsunuz?

$customer = Mockery::mock(CustomerModel::className())->makePartial(); 
echo $customer->id; 

Yukarıdaki örnek, id ayarlanmadığı için hiçbir şey döndürmez, ancak herhangi bir hata atmayacaktır.

+0

Bence bu ilk etapta bir problem. Bu yaklaşım, ActiveRecord açısından kalıcı olmayan yeni '' CustomerModel'' örneğini oluşturur. Aynı zamanda id ile dalga geçemezsiniz çünkü bir şekilde "$ customer-> id = 123" değeri atanmaz – paulus