Reputation: 257
I am desperately trying to unit test a module for a shopsystem. That shop system uses static methods which I have to call in my functions I want to test.
public function toTest() {
$value = \Context::getData();
return $value;
}
Now how can I unit test that function while mocking this static call? I tried using AspectMock but that does not work because it apparently needs access to the original \Context class which is not available since it's an external system. I also tried using class_alias to create my own Context class but that does not work either because I need different Context output depending on which function I am testing. And setting class_alias multiple times for different tests does not work because the same class can't be declared multiple times and @runTestsInSeparateProcesses did not have the expected effect.
Edit: None of the duplicates provided a viable solution to my situation, so I don't think this is a duplicate. With no access to the shopsystem code and especially with hard to maintain code like that, PHP does not make it easy to unit test this. Also the solution I found should help others with similar settings.
Upvotes: 5
Views: 8971
Reputation: 257
I could solve my issue with the Mockery library. I tried out a few but nothing worked. With Mockery everything seems possible now. This link really helped: https://robertbasic.com/blog/mocking-hard-dependencies-with-mockery/
You can easily mock static calls to classes that don't belong to you:
public function methodToTest() {
return \Context::getData();
}
public function testMethodToTest() {
m::mock('alias:\Context')
->shouldReceive('getData')
->andReturn('foo');
}
And even instantiations for classes you don't have access to:
public function methodToTest() {
$obj = new \Category(5);
return $obj->id;
}
public function testMethodToTest() {
m::mock('overload:\Category')
->shouldReceive('__construct')
->with(5)
->andSet('id', 5);
}
But you have to keep in mind that you need the two phpunit annotations at the beginning of the class:
* @runTestsInSeparateProcesses
* @preserveGlobalState disabled
Upvotes: 4