简体   繁体   English

模拟不存在于任何类中的函数的调用(例如 php 标准函数)以具有固定行为

[英]Mock the call of a function that exists in no class (eg php standart functions) in order to have fixed behavior

I have the following class:我有以下课程:

namespace Utils\Random;

class RandomHelper
{   

   const LUCKY_NUMBER=3;

   public static function lucky()
   {
      return rand(0,6)==self::LUCKY_NUMBER;
   }    
}

And I want to test this class using a unit test:我想使用单元测试来测试这个类:


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
   }
}

But in order my test to be a Unit test I want to mock the php standart function rand in order to be able to have a constant result in my test.但是为了让我的测试成为单元测试,我想模拟 php 标准函数rand以便能够在我的测试中获得恒定的结果。

As you can see I have conflicting needs, therefore the solution seems not to be ok with me.正如您所看到的,我有相互冲突的需求,因此该解决方案似乎不适合我。 On one test I want to check when ther method lucky teturns true and on the other hand I want to be able when the function lucky will return false.在一个测试中,我想检查方法lucky teturns 何时为真,另一方面我希望能够在函数lucky 返回false 时进行检查。

So do you have any idea hot to do that?那么你有什么想法可以这样做吗?

The most painless way to do that is via php-mock/php-mock-phpunit package.php-mock/php-mock-phpunit方法是通过php-mock/php-mock-phpunit包。

In your case the correct usage is:在您的情况下,正确的用法是:

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);
   }
}

As you can see you can utilize as @Anton Mitsev says the php-mock and on the class's namespace you stub the method you want the fixed and controlled behaviour.正如您所看到的,您可以使用@Anton Mitsev 所说的 php-mock,并且在类的命名空间上,您可以将想要固定和受控行为的方法存根。

So a simple rule of thumb is:所以一个简单的经验法则是:

  1. In not included run composer require --dev php-mock/php-mock-phpunit在不包括运行composer require --dev php-mock/php-mock-phpunit
  2. On each test, include the \\phpmock\\phpunit\\PHPMock trait在每个测试中,包括\\phpmock\\phpunit\\PHPMock trait
  3. Find your class' namespace.找到你的类的命名空间。
  4. Mock the function using the following approach:使用以下方法模拟函数:
 $functionMock=$this->getFunctionMock(^class_namespace^,^function_name^);
 $functionMock->expects(^expected_call_times^)->willReturn(^values^);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM