Смоделируйте вызов функции, которая не существует ни в одном классе (например, стандартные функции php), чтобы иметь фиксированное поведение - PullRequest
1 голос
/ 02 июля 2019

У меня есть следующий класс:

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 standart rand, чтобы иметь постоянный результат в моем тесте.

Как видите, у меня противоречивые потребности, поэтому решение , похоже, мне не подходит. В одном тесте я хочу проверить, когда один из методов lucky равен true, а с другой стороны, я хочу иметь возможность, когда функция lucky вернет false.

Так у тебя есть какая-нибудь горячая идея сделать это?

1 Ответ

1 голос
/ 02 июля 2019

Самый безболезненный способ сделать это через пакет php-mock/php-mock-phpunit.

В вашем случае правильное использование:

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-mock, и в пространстве имен класса вы задаете нужный методфиксированное и контролируемое поведение.

Итак, простое правило:

  1. В не включенный прогон composer require --dev php-mock/php-mock-phpunit
  2. В каждом тесте включайте \phpmock\phpunit\PHPMock trait
  3. Найдите пространство имен вашего класса.
  4. Смоделируйте функцию, используя следующий подход:
 $functionMock=$this->getFunctionMock(^class_namespace^,^function_name^);
 $functionMock->expects(^expected_call_times^)->willReturn(^values^);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...