2016-12-29 9 views
1

У меня есть вопрос относительно тестирования некоторого метода вызывает x раз с конкретными аргументами.Метод проверки PHPUnit вызывается несколько раз с конкретными аргументами без какого-либо определенного порядка.

Ситуация:

У меня есть класс Grid. Он обрабатывает двумерный массив. Он содержит метод

public function setCell($x, $y, $value) : void 

, который устанавливает значение $ value в координатах $ x и $ y.

Далее У меня есть класс 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]] 

Проблема:

Я хочу проверить метод shiftRow из GridShifter без тестирования функциональности setCell класса сетки на насмешливый это метод и проверяет, сколько раз этот метод вызывается (для этого примера 3) и проверяет аргументы вызовов.

решения, которые не работали для меня:

Я пробовал несколько решений. $ gridMock - макет класса Grid.

1) withConsecutive или ($ х)

$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] 
]); 

Это не проверить мои потребности. В этом случае тесты будут также проходить, когда setCell вызывается три раза с аргументами 1, 1 и 3, не вызывая setCell с другими аргументами

3) withConsecutive с logicalOr

$gridMock->expect($this->exactly(3))->method('setCell')->withConsecutive(
    $this->logicalOr(
     [1, 1, 3], 
     [1, 2, 2], 
     [1, 3, 1] 
    ) 
); 

Это проходит мои тесты слишком но имеет ту же проблему, что и решение 2. Он не проверяет, вызываются ли все три набора аргументов.

Может кто-нибудь подумать о решении, которое будет проверять setCell, вызывается трижды в shiftCell с каждым прохождением разных заданных аргументов в любом порядке?

Вышеприведенные классы и примеры упрощены. Он описывает мою ситуацию, но это не моя точная ситуация. Все важные детали в этом вопросе.

Заранее спасибо

ответ

0

withCallback это путь, когда встроенные методы не работают. Добавьте ожидаемые аргументы в массив, затем в проверку обратного вызова, если аргументы присутствуют в массиве (в определенном порядке) - если это так, удалите их из массива (так что в 2 раза те же аргументы не пройдут тест); если нет - не прошел тест

Ограничение обратного вызова() может использоваться для более сложного аргумента проверка. Это ограничение принимает обратный вызов PHP как единственный аргумент . Обратный вызов PHP получит аргумент, который будет проверен как , его единственный аргумент и должен возвращать значение true, если аргумент проходит подтверждение и false в противном случае.

Из инструкции PHPUnit - Test doubles

0

Вы можете использовать закрытие обратного вызова для этого. Пример:

$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 будут содержать полную запись о том, как был выполнен метод. Вы можете пройти его и проверить, как вам нужно.