簡體   English   中英

如何單元測試實例創建?

[英]How to unit test instance creation?

我有一個Carpenter類,使用LatheWood對象完成它的工作。

class Carpenter
{
    function Work()
    {
        $tool = new Lathe();
        $material = new Wood();
        $tool->Apply($material);
    }
}

Lathe依賴於一個名為Material的接口,所以我可以通過在我的單元測試中給它一個假Material來輕松地對Lathe進行單元測試。 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
    }
}

然而, Carpenter依賴於LatheWood的具體類,因為它必須創建它們的實例。 這意味着,就目前的情況而言,我不能對Work()方法進行單元測試,而不會無意中將LatheWood置於測試之中。

我應該如何將我的設計改為單元測試Carpenter

您可以在這里找到幾個不同的方向:

  • 使用構造函數注入 ,只需將工具和材質實例注入木匠。
  • 如果注入實例由於某種原因不起作用(可能因為您需要為每次調用Work方法創建新實例),則可以注入Abstract Factories
  • 您也可以使用ctford描述的工廠方法方法,但這需要您創建特定於測試的覆蓋以便能夠進行單元測試,雖然這是一個完全有效的事情,但它只是更多的工作,在很多情況下是另一個替代方案更好,更靈活。

關鍵是要從Carpenter對象使用中分離對象創建。

class Carpenter
{
    function getTool() {
        return new Lathe();
    }
    function getMaterial() {
        return new Wood();
    }
    function Work()
    {
        $tool = getTool();
        $material = getMaterial();
        $tool->Apply($material);
    }
}

這樣,您可以覆蓋TestCarpenter類中的getTool()getMaterial()方法,並注入您自己的MaterialTool假貨。

getTool()getMaterial()方法也可以單獨進行單元測試。

Michael Feathers會將getTool()getMaterial()方法getMaterial() “接縫”,因為它們是可以在不更改周圍代碼的情況下插入偽造的點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM