如何在PHP中对具有依赖项的方法进行单元测试?

时间:2011-04-06 05:06:59

标签: php unit-testing

我有一个方法,里面有一些逻辑,我不知道如何对它进行单元测试。因为它是这个特定方法的单元测试,所以它应该在不连接数据库的情况下运行。我读到了存根和模型,但我找不到将它们应用于这种情况的方法。

我想强制客户端:GetClient返回具有正确属性的客户端对象,以便我可以测试每个逻辑分支。


class ClientType {
    function GetClientType($id) {

    $objClient = Client::GetClient($id);

    if ($objClient->Returning == 1) {
        return 'returning';
    }
    else {
        return 'normal';
    }
    }


这是我心中的考验


class ResourceTest extends PHPUnit_Framework_TestCase {
    function testGetClientType() {
        $objClientType = new ClientType();
        $this->assertTrue($objClientType->GetClientType(100), 'normal');
    }
}

问题是依赖$ objClient = Client :: GetClient($ id); GetClient将从数据库中提取客户端,但我需要将其替换为Stub,以便单元测试工作而无法真正访问数据库。

结论

  • 如果你有像所呈现的代码:重构它并使用依赖注入。
  • 如果您有遗留代码或者只是不想重构,请尝试使用此解决方案:http://sebastian-bergmann.de/archives/885-Stubbing-Hard-Coded-Dependencies.html

  • 2 个答案:

    答案 0 :(得分:5)

    使用PHPUnit即可

      $class = $this->getMockClass(
          'Client',          /* name of class to mock     */
          array('getClient') /* list of methods to mock   */
        );
        $class::staticExpects($this->any())
              ->method('getClient')
              ->will($this->returnValue('foo'));
    

    通常,您希望避免使用静态方法:


    更新后编辑

    PHPUnit还可以存根硬编码的依赖项。参见

    但是,既然你已经注意到它是一个测试静态和硬编码依赖的痛苦,我建议你删除硬编码的依赖和静态调用,而不是你注入ClientType的真实对象。

    另一个选择是使用http://antecedent.github.io/patchwork(不隶属于它),

      

    是一个PHP库,可以重新定义用户定义的函数和方法   在运行时,在纯PHP 5.3代码中松散地复制runkit_function_redefine功能,   除其他外,它允许您使用测试双精度替换静态和私有方法。

    答案 1 :(得分:0)

    尝试模拟这种问题。我不懂PHP,但我们在这种情况下用Java和C#进行模拟。

    修改

    对不起,我没有看到你遇到嘲笑的问题。通常对于模拟你告诉他们你对他们的期望,他们也会回应。 LSV原理正在模拟中使用。至于PHP,我很抱歉我不知道什么工具可用于模拟以及如何使用它们