Вопрос:
Как протестировать функцию в PHPUnit, которая умножает аргумент на случайное число и возвращает результат умножения?
Ответ:
Чтобы протестировать функцию, использующую случайные числа, в PHPUnit можно воспользоваться мок-объектом и заменить генератор случайных чисел на контролируемый тестами источник псевдослучайных чисел.
Ньюанс: не достаточно переопределить ф-ю getRand, ф-ю ее вызывающую также обновить нужно: иначе она вызовет оригинальную getRand()
Например:
Нужно протестировать multiplyByRandom в классe: Randomizer.php
<?php
/**
* Класс со случайным числом
*/
class Randomizer
{
/**
* @return int
*/
public function getRand(): int
{
return mt_rand(1, 10);
}
/** Тестируемая функция
* @param int $num
* @return int
*/
public function multiplyByRandom(int $num): int
{
return $num * $this->getRand();
}
}
Скрипт тестирования: MultTest.php
<?php
use PHPUnitFrameworkTestCase;
require_once("Randomizer.php");
class MultTest extends TestCase
{
// Тест рандомной функции
public function testMultiply()
{
// Создаем мок
$randMock = $this->createStub(Randomizer::class);
// Задаем последовательность значений
$randMock->expects($this->exactly(4))
->method('getRand')
->willReturnOnConsecutiveCalls(2, 7, 6, 5);
// Не достаточно переопределить ф-ю getRand,
// ф-ю ее вызывающую также обновить нужно: иначе она вызовет оригинальную getRand()
$randMock->expects($this->exactly(4))
->method('multiplyByRandom')
->willReturnCallback(function (&$x) use ($randMock) {
return $x * $randMock->getRand();
});
// Инжектим мок в функцию и Проверяем результат
$result = $randMock->multiplyByRandom(3);
$this->assertEquals(6, $result); // 2 * 3 = 6
$result = $randMock->multiplyByRandom(10);
$this->assertEquals(70, $result); // 10 * 7 = 70
$result = $randMock->multiplyByRandom(20);
$this->assertEquals(120, $result); // 20 * 6 = 120
$result = $randMock->multiplyByRandom(0);
$this->assertEquals(0, $result); // 0 * 5 = 0
}
}
Таким образом мы имитируем поведение Randomizer и можем протестировать функцию для разных фиксированных случайных значений.
PS: рекомендую к изучению курс “Otus php professional“ (который я прошел), там рассматривается глубоко в т.ч. тема тестирования веб-приложений

Нет Ответов