phpunit-模拟外部静态方法

时间:2018-11-26 13:05:46

标签: php unit-testing phpunit

我拼命尝试对shopsystem的模块进行单元测试。该车间系统使用静态方法,必须在要测试的函数中调用。

public function toTest() {
    $value = \Context::getData();
    return $value;
}

现在如何在模拟此静态调用时如何对该功能进行单元测试?我尝试使用AspectMock,但是那不起作用,因为它显然需要访问原始\ Context类,该类由于是外部系统而无法使用。我也尝试过使用class_alias创建自己的Context类,但这也不起作用,因为我需要不同的Context输出,具体取决于要测试的功能。为不同的测试多次设置class_alias无效,因为无法多次声明同一个类,并且@runTestsInSeparateProcesses没有预期的效果。

编辑:没有重复项可以为我的情况提供可行的解决方案,因此我不认为这是重复项。由于无法访问shopsystem代码,尤其是难以维护的代码,因此PHP很难对其进行单元测试。另外,我发现的解决方案应该可以帮助其他设置类似的人。

1 个答案:

答案 0 :(得分:1)

我可以使用Mockery库解决问题。我尝试了一些,但没有任何效果。有了Mockery,现在似乎一切皆有可能。该链接确实有帮助:https://robertbasic.com/blog/mocking-hard-dependencies-with-mockery/

您可以轻松地模拟对不属于您的类的静态调用:

public function methodToTest() {
    return \Context::getData();
}

public function testMethodToTest() {
    m::mock('alias:\Context')
        ->shouldReceive('getData')
        ->andReturn('foo');
}

甚至是您无权访问的类的实例:

public function methodToTest() {
    $obj = new \Category(5);
    return $obj->id;
}

public function testMethodToTest() {
    m::mock('overload:\Category')
        ->shouldReceive('__construct')
        ->with(5)
        ->andSet('id', 5);
}

但是您要记住,在类的开头需要两个phpunit注释:

* @runTestsInSeparateProcesses
* @preserveGlobalState disabled