[英]PHPUnit test method is called multiple times with specific arguments in no specific order
我有一個關於測試一些方法調用x次特定參數的問題。
情況:
我有一個Grid類。 它處理一個二維數組。 它包含一種方法
public function setCell($x, $y, $value) : void
它在坐標$ x和$ y處設置值$ value。
接下來我有一個GridShifter類。 它包含一種方法
public function shiftRow($grid : Grid, $rowNumber : int) : void
此方法將行號$ rowNumber處的所有值向右移動。 例如:
$grid = new Grid([[1, 2, 3]]);
$gridShifter->shiftRow($grid, 1);
// prints two dimensional array
print_r($grid->printGrid());
會導致
[[3, 1, 2]]
問題:
我想測試GridShifter的shiftRow方法,而不是通過模擬this方法測試Grid類的setCell功能,並檢查調用該方法的次數(對於此示例3)並檢查調用的參數。
解決方案對我不起作用:
我嘗試了幾種解決方案。 $ gridMock是Grid類的模擬。
1)withConsecutive或at($ x)
$gridMock->expect($this->exactly(3))->method('setCell')->withConsecutive(
[1, 1, 3],
[1, 2, 2],
[1, 3, 1]
);
這通過了我的測試,但這對我不起作用,因為它也測試了它執行的順序。我對它們被調用的順序不感興趣。
2)returnValueMap
$gridMock->expect($this->exactly(3))->method('setCell')->will($this-returnValueMap([
[1, 1, 3],
[1, 2, 2],
[1, 3, 1]
]);
這不能測試我的需求。 在這種情況下,當使用參數1,1和3調用setCell三次時,測試也將通過,而不使用其他參數調用setCell
3)withConsecutive with logicalOr
$gridMock->expect($this->exactly(3))->method('setCell')->withConsecutive(
$this->logicalOr(
[1, 1, 3],
[1, 2, 2],
[1, 3, 1]
)
);
這也通過了我的測試,但與解決方案2有相同的問題。它不測試是否調用所有三組參數。
有人會想到一個解決方案,測試setCell在shiftCell中被調用三次,每次都以任何順序傳遞不同的指定參數嗎?
上面的類和示例是簡化的。 它描述了我的情況,但這不是我的確切情況。 所有重要細節都在這個問題中。
提前致謝
當內置方法不起作用時, withCallback
是要走的路。 在數組中添加預期的參數,然后在回調中檢查數組中是否存在參數(按特定順序) - 如果是,則從數組中刪除它們(因此相同參數的2次將無法通過測試); 如果沒有 - 測試失敗
callback()約束可用於更復雜的參數驗證。 此約束將PHP回調作為其唯一參數。 PHP回調將接收要驗證為其唯一參數的參數,如果參數通過驗證則返回true,否則返回false。
從PHPUnit手冊 - 測試雙打
您可以使用回調閉包。 例:
$executions = [];
$grid = $this->getMockBuilder('Grid')->getMock();
$grid->expects($this->any())->method('setCell')->will($this->returnCallback(
function($x, $y, $value) use ($executions) {
$executions[] = func_get_args();
}
));
執行后,變量$ executions將包含方法執行方式的完整記錄。 您可以遍歷它並檢查您的需求。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.