2015-07-03 19 views
6

Tôi đang chạy phpunit với sự nhạo báng (không có DB/đồ đạc), nhưng tôi gặp rắc rối với chế nhạo một mô hình.Yii2 ActiveRecord chế nhạo với Mockery

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

Tạo lỗi:

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

Sau đó, tôi đã cố gắng:

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

Nhưng một lần nữa, tôi chạy vào:

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

Mọi đề xuất?

Trả lời

2

Tôi biết bạn không chấp nhận câu trả lời lịch thi đấu, nhưng tôi cũng không thể tìm ra câu trả lời. Vấn đề tôi đã cố gắng giải quyết thực sự là chế nhạo một số phương thức trong mô hình để tránh tạo ra các đồ đạc cơ bản.

Vì vậy, tôi đã kết thúc bằng Proxy mẫu thực hiện trong 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 
    ... 
} 

Trong ví dụ phương pháp getPrice() này từ Product mô hình trả Product giá từ các bảng liên quan. Và chúng tôi giả lập nó ở đây để chúng tôi sẽ không phải điền db với tất cả các đồ đạc mô hình liên quan. Tuy nhiên Product chính nó vẫn là một vật cố định.

Có lẽ không phải là giải pháp tốt nhất, nhưng quản lý để tiết kiệm cho tôi một số thời gian CPU trong khi vẫn giữ các bài kiểm tra đơn vị được tách riêng.

Documents đây http://docs.mockery.io/en/latest/reference/partial_mocks.html

cập nhật:

Tôi cũng làm một helper nhỏ để giải quyết thuộc tính proxy vấn đề

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

Bằng cách này tất cả các thuộc tính và giá trị tương ứng của họ từ mô hình ban đầu trở thành có sẵn trong mô hình.

+0

Cảm ơn, tôi sẽ dùng thử! –

1

Có phải Traditional Partial Mock hoặc Passive Partial Mock những gì bạn đang tìm kiếm?

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

Mẫu ở trên tất nhiên sẽ không trả lại bất kỳ điều gì vì id không được đặt nhưng sẽ không phát sinh bất kỳ lỗi nào.

+0

Tôi nghĩ rằng đây là một vấn đề ở nơi đầu tiên. Cách tiếp cận này tạo ra cá thể '' CustomerModel'' mới không liên tục trong điều khoản của ActiveRecord. Đồng thời bạn không thể giả lập id bởi vì bằng cách nào đó '' $ customer-> id = 123'' sẽ không gán giá trị – paulus

Các vấn đề liên quan