Trying to test some code, I’m using php-mock to mock a native php function so I can check my code handles situations correctly where the native php function doesn’t return what is expected.
In my actual code I’m mocking fputcsv, but to make a simple example, here’s a class and test using mt_rand mocked:
Class / method being tested:
namespace MyNS;
class MyClass
{
public function myMethod()
{
if (!mt_rand(1, 10)) {
return false;
}
return true;
}
}
Test:
namespace MyNS;
use phpmock\phpunit\PHPMock;
class MyTest extends \PHPUnit_Framework_TestCase
{
use PHPMock;
protected $_MyClass;
public function setUp()
{
$this->_MyClass = new MyClass();
}
public function test_normal()
{
$result = $this->_MyClass->myMethod();
$this->assertSame(true, $result);
}
public function test_mt_rand_fails()
{
$mt_rand = $this->getFunctionMock(__NAMESPACE__, 'mt_rand');
$mt_rand->expects($this->at(0))
->with(1,10)
->willReturn(false);
$result = $this->_MyClass->myMethod();
$this->assertSame(false, $result);
}
}
The second test fails because the method for some reason returns true, not false as it should with the mocked mt_rand. If I remove the assertion from the second test then I will get an error that the mocked mt_rand was never called.
If I switch the order of the tests, so test_mt_rand_fails occurs before test_normal, then both tests will pass.
Thanks for that, you’re right - the double use statements seem a bit pointless. I’ve changed it now to remove the use statement below the namespace declaration and changed the class to use \phpmock\phpunit\PHPMock; instead.
However, I still get the same results. The reason I need to use use \phpmock\phpunit\PHPMock; is so I can import the PHPMock traits (namely the getFunctionMock method) into the test.
I’m using DI in my real class, but for this example class that demonstrates my problem, there isn’t anything that could be injected.
What it looks like to me is that when a function has already been called once within the set of tests, then you can’t stub that function - the native function will always be called instead. As far as I’m aware that’s not meant to be the way php-mock works though. My understanding is that php should check for the existence of the namespaced (stubbed) function before it falls back to the non-namespaced native function each time the function is called.