gpt4 book ai didi

php - 如何以一定的随机性对函数进行单元测试

转载 作者:行者123 更新时间:2023-12-02 07:39:08 25 4
gpt4 key购买 nike

我有一个返回 0 到 6 之间的三个随机元素数组的函数。它确保所有元素不能具有相同的值(可以有两个具有相同值的元素,但不能有三个)。以下是示例代码。

public function getRandom() {
$array = array(0, 0, 0);
do {
$array[0] = rand(0, 6);
$array[1] = rand(0, 6);
$array[2] = rand(0, 6);
} while(($array[0] == $array[1]) && ($array[0] == $array[2]));
return $array;
}

我对单元测试有点陌生,我唯一能想到测试这个的是

  1. 测试此函数 1,000 次,检查它是否返回 0 到 6 之间的数据,并且所有三个元素不能具有相同的值。
  2. 找到一种方法来重写函数 rand() ,以便它返回我们想要的内容:
    • 返回三个元素值相同的值,然后返回两个元素值相同的值。然后,返回所有元素具有不同值的值。

我想知道是否有任何方法或者我的哪种方法更适合这种情况。

最佳答案

正如您所猜测的那样,您无法真正可靠地测试随机性。

控制随机性的问题显示了您的架构中的弱点:您有一个想要测试的类和方法,但您无法控制正在调用的函数(rand())测试期间。

一开始可能听起来很奇怪,但如果你想用“受控”随机性进行测试,你需要以某种方式模拟随机函数,所以你需要一个 PHP 函数的包装器,允许拦截调用并返回定义的测试测试期间的值。

想一想:如果您有一个具有随机方法的类,并且该类的实例被注入(inject)到您的测试类中以提供随机值,您可以在测试期间模拟该对象并定义返回值。任务完成。 :)

现在实例化一个具有单一方法 rand() 的对象听起来很奇怪,该方法将所有调用传递给同名的 PHP 函数。更奇怪的是,需要在运行时将该对象传递给被测试的类才能使其工作。但您不必具有运行时依赖性。您还可以重构您的测试类,仅查看是否注入(inject)了随机性提供程序并使用它,如果没有,则直接使用 rand()

如果您希望减少对类的修改,可以使用一个技巧来覆盖内置 PHP 函数:如果您的类位于命名空间内并调用 native PHP 函数,则该函数将首先在该命名空间内搜索。如果您在测试文件中与测试类位于同一命名空间中声明一个名为 rand() 的函数,则该类将调用命名空间函数而不是 PHP 函数。然后,您只需考虑如何预定义该模拟函数的返回值,但您可能可以使用全局变量或测试用例类的静态属性来填充预定义的“随机性”:

namespace MyNameSpace;
function rand() {
return array_shift(RandomTest::$randomValues);
}

class RandomTest extends PHPUnit_Framework_TestCase {
public static $randomValues = array();
public function testSomeRandomness() {
self::$randomValues = array(0,0,0,0,1,2);
// ... test
}
}

如果我有这份工作,我会选择真正的 PHPUnit 模拟对象,一个将其注入(inject)到类中的 setter,并将其编码为默认调用 rand() 的可选依赖项>.

关于php - 如何以一定的随机性对函数进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18741147/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com