模拟不存在于任何类中的函数的调用(例如php标准函数),以获得固定的行为
我有以下课程:模拟不存在于任何类中的函数的调用(例如php标准函数),以获得固定的行为,php,phpunit,Php,Phpunit,我有以下课程: namespace Utils\Random; class RandomHelper { const LUCKY_NUMBER=3; public static function lucky() { return rand(0,6)==self::LUCKY_NUMBER; } } 我想用单元测试来测试这个类: namespace Tests\Random; use PHPUnit\Framework\TestCase
namespace Utils\Random;
class RandomHelper
{
const LUCKY_NUMBER=3;
public static function lucky()
{
return rand(0,6)==self::LUCKY_NUMBER;
}
}
我想用单元测试来测试这个类:
namespace Tests\Random;
use PHPUnit\Framework\TestCase;
class RandomHelperTest extends TestCase
{
public function testLucky()
{
// Mock rand here
// Here I want the rand return a value that is not 3
}
public function testLuckyFails()
{
// Mock rand here
// Here I want the rand return a value that is not 3
}
}
但是为了使我的测试成为一个单元测试,我想模拟php标准函数rand
,以便能够在我的测试中得到一个恒定的结果
正如你所看到的,我有相互冲突的需求,因此,我似乎不适合这种情况。在一个测试中,我想检查方法lucky
teturns何时为true,另一方面,我想能够检查函数lucky何时返回false
那你有什么办法吗 最无痛的方法是通过软件包 在您的情况下,正确的用法是:
namespace Tests\Random;
use PHPUnit\Framework\TestCase;
use Utils\Random\RandomHelper;
class RandomHelperTest extends TestCase
{
use \phpmock\phpunit\PHPMock;
public function testLucky()
{
$rand=$this->getFunctionMock('Utils\Random', "rand");
$rand->expects($this->once())->willReturn(RandomHelper::LUCKY_NUMBER);
$boolean=RandomHelper::lucky();
$this->assertTrue($boolean);
}
public function testLuckyFails()
{
$rand=$this->getFunctionMock('Utils\Random', "rand");
$rand->expects($this->once())->willReturn(0);
$boolean=RandomHelper::lucky();
$this->assertFalse($boolean);
}
}
正如您所见,您可以利用@Anton Mitsev所说的php模拟,并在类的名称空间上存根您想要固定和控制行为的方法
因此,一个简单的经验法则是:
composer require--dev-php-mock/php-mock-phpunit
\phpmock\phpunit\phpmock
特征如果它是专门针对
rand
的,那么您可以在测试启动中运行它。如果你使用相同的数字,那么你总是会得到相同的“随机”数字生成。一般来说,您应该尽量避免模拟标准函数。在您的特定情况下,您还可以将RandomHelper
更改为不包含静态成员,并对此进行模拟。我发现了一个用于此目的的包:我更新了问题,以便更好地解释我的需求。您不能使用$v=3;//您可以将其更改为幸运数字
$a=rand(0,6)
而($a!=$v){a$=rand(0,6);}
//在这一行中,$a是一个非3的随机值
//可以随意使用它
实现是虚拟的,以便能够解释我的问题。我可以在循环中调用Helper::lucky()
,直到它为真。
$functionMock=$this->getFunctionMock(^class_namespace^,^function_name^);
$functionMock->expects(^expected_call_times^)->willReturn(^values^);