Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/244.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
模拟不存在于任何类中的函数的调用(例如php标准函数),以获得固定的行为_Php_Phpunit - Fatal编程技术网

模拟不存在于任何类中的函数的调用(例如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模拟,并在类的名称空间上存根您想要固定和控制行为的方法

因此,一个简单的经验法则是:

  • 在未包含的run
    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^);