2011-04-29 21 views
39

Tôi muốn gọi phương thức giả của tôi hai lần với các đối số dự kiến ​​khác nhau. Điều này không hoạt động vì expects($this->once()) sẽ không thực hiện được cuộc gọi thứ hai.Trong PHPUnit, làm thế nào để tôi chỉ ra khác với() trên các cuộc gọi liên tiếp đến một phương thức giả?

$mock->expects($this->once()) 
    ->method('foo') 
    ->with('someValue'); 

$mock->expects($this->once()) 
    ->method('foo') 
    ->with('anotherValue'); 

$mock->foo('someValue'); 
$mock->foo('anotherValue'); 

Tôi cũng đã cố gắng:

$mock->expects($this->exactly(2)) 
    ->method('foo') 
    ->with('someValue'); 

Nhưng làm thế nào để tôi thêm một với() để phù hợp với cuộc gọi thứ hai?

+2

Tại sao bạn cần đối sánh các đối số? Bạn không thể sử dụng onConsecutiveCalls() để nói "lần đầu tiên, trả về điều này, lần thứ hai trả về"? Bạn muốn sử dụng chính xác (2) và onConsecutiveCalls() – fiunchinho

+2

cùng một [câu hỏi] (http://stackoverflow.com/questions/5484602/mock-in-phpunit-multiple-configuration-of-the-same-method-with -different-argume) từ khối liên quan. – meze

+2

Có thể trùng lặp của [phpunit phương pháp giả lập nhiều cuộc gọi với các đối số khác nhau] (https://stackoverflow.com/questions/5988616/phpunit-mock-method-multiple-calls-with-different-arguments) –

Trả lời

51

Bạn cần phải sử dụng at():

$mock->expects($this->at(0)) 
    ->method('foo') 
    ->with('someValue'); 

$mock->expects($this->at(1)) 
    ->method('foo') 
    ->with('anotherValue'); 

$mock->foo('someValue'); 
$mock->foo('anotherValue'); 

Lưu ý rằng các chỉ số truyền cho at() áp dụng trên tất cả các phương pháp các cuộc gọi đến các đối tượng giả tương tự. Nếu cuộc gọi phương thức thứ hai là bar(), bạn sẽ không thay đổi đối số thành at().

7

Tham khảo từ the answer from a similar question,

Kể từ PHPUnit 4.1 bạn có thể sử dụng withConsecutive ví dụ.

$mock->expects($this->exactly(2)) 
    ->method('set') 
    ->withConsecutive(
     [$this->equalTo('foo'), $this->greaterThan(0)], 
     [$this->equalTo('bar'), $this->greaterThan(0)] 
     ); 

Nếu bạn muốn làm cho nó trở lại các cuộc gọi liên tiếp:

$mock->method('set') 
     ->withConsecutive([$argA1, $argA2], [$argB1], [$argC1, $argC2]) 
     ->willReturnOnConsecutiveCalls($retValueA, $retValueB, $retValueC); 

Đó không phải là lý tưởng để sử dụng at() nếu bạn có thể tránh nó vì as their docs claim

Tham số $ index cho tại() matcher đề cập đến chỉ mục, bắt đầu từ số không, trong tất cả các phương thức invocations cho một đối tượng giả định đã cho. Thận trọng khi sử dụng bộ ghép này vì nó có thể dẫn đến các xét nghiệm giòn quá chặt chẽ với các chi tiết thực hiện cụ thể.

+0

Vâng, đó là một thực sự ngu ngốc giải pháp trong phpunit. Mọi người đều bị lừa bởi thực tế này, ví dụ: https://addshore.com/2015/08/misled-by-phpunit-at-method/ – forsberg

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