Reputation: 10086
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.
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.
So do you have any idea hot to do that?
Upvotes: 1
Views: 560
Reputation: 10086
The most painless way to do that is via php-mock/php-mock-phpunit
package.
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.
So a simple rule of thumb is:
composer require --dev php-mock/php-mock-phpunit
\phpmock\phpunit\PHPMock
trait $functionMock=$this->getFunctionMock(^class_namespace^,^function_name^);
$functionMock->expects(^expected_call_times^)->willReturn(^values^);
Upvotes: 1