如何单元测试实例创建?

ctf*_*ord 4 unit-testing dependency-injection

我有一个Carpenter类使用a LatheWoodobject 来完成它的工作.

class Carpenter
{
    function Work()
    {
        $tool = new Lathe();
        $material = new Wood();
        $tool->Apply($material);
    }
}
Run Code Online (Sandbox Code Playgroud)

Lathe取决于所谓的接口Material,所以我可以Lathe通过在单元测试中给它假装来轻松进行Material单元测试.Wood不依赖于任何东西,所以它也可以很容易地测试.

interface Material {
    // Various methods...
}

interface Tool {
    function Apply(Material $m);
}

class Wood implements Material  {
    // Implementations of Material methods
}

class Lathe {
    function Apply(Material $m) {
        // Do processing
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,Carpenter取决于具体的类Lathe,Wood因为它必须创建它们的实例.这意味着,就目前的情况而言,我不能对该Work()方法进行单元测试而不会无意中带来LatheWood测试.

我应该如何将设计更改为单元测试Carpenter

Mar*_*ann 5

您可以在这里找到几个不同的方向:

  • 使用构造函数注入,只需将工具和材质实例注入木匠.
  • 如果注入实例由于某种原因不起作用(可能因为您需要为每次调用Work方法创建新实例),则可以注入Abstract Factories.
  • 您也可以使用ctford描述的工厂方法方法,但这需要您创建特定于测试的覆盖以便能够进行单元测试,虽然这是一个完全有效的事情,但它只是更多的工作,在很多情况下是另一个替代方案更好,更灵活.