簡體   English   中英

如何對一個只調用其他函數的函數進行單元測試?

[英]How to unit test a function, which just calls other functions?

我的代碼庫(遺留)中有一個函數,它具有:

function test()
{
 method1("#input a")
 method2("test")
 method3(1,2)
}

鑒於它調用其他methods的事實,如何為這些函數編寫一個好的單元測試?

首先,我不認為你描述的這種行為甚至需要進行單元測試。 但是,如果您確實需要檢查是否使用特定參數(甚至任何參數)調用方法。 有一種方法可以做到這一點,你可以使用像ShortifyPunit這樣的模擬框架: https//github.com/danrevah/ShortifyPunit

請遵循以下步驟:

  1. 確保附加到可以模擬的對象的方法
  2. 將模擬對象注入您的類並存根方法
  3. 您可以驗證()使用特定參數調用方法

例如,如果您的類正在使用依賴注入,這對於單元測試至關重要,如下面的類:

class SomeClass {

    private $obj;

    public function __construct($obj) {
        $this->obj = $obj;
    }

    public function test()
    {
        $this->obj->method1("#input a")
        $this->obj->method2("test")
        $this->obj->method3(1,2)
    }
}

您可以編寫單元測試,如下所示:

public function testMethodCalled()
{
    $mockedObj = ShortifyPunit::mock('object');

    $class = new SomeClass($mockedObj);

    // Stub the methods so you could verify they were called
    ShortifyPunit::when($mockedObj)->method1(anything())->returns(1);
    ShortifyPunit::when($mockedObj)->method2(anything())->returns(2);
    ShortifyPunit::when($mockedObj)->method3(anything(), anything())->returns(3);

    $class->test(); // run test() method

    // Verify it was called
    $this->assertTrue(ShortifyPunit::verify($mockedObj)->method1(anything())->calledTimes(1));
    $this->assertTrue(ShortifyPunit::verify($mockedObj)->method2(anything())->calledTimes(1));
    $this->assertTrue(ShortifyPunit::verify($mockedObj)->method3(anything(), anything())->calledTimes(1));
}

鑒於它調用其他methods的事實(...)

它所謂的並不重要。 從消費者(來電者)的角度來看, 最終結果很重要。 你總是測試最終結果。 調用其他一些方法的事實是無關的實現細節 (在大多數情況下)。

我建議簡單的練習-內聯method1method2method3機構進入test方法。 你在確定要測試的內容時遇到問題嗎?

您希望測試公共契約或可觀察行為 - 方法調用的最終結果對於調用它的人可見(許多不同的actor可能會調用您的方法 - 程序的其他部分,單元測試或系統用戶;每個應該經歷相同的可觀察行為 )。

現在,回到幾次提到的“最終結果”/“方法的可觀察行為”。 它可以是三件事之一:

  • 返回值(您的方法不這樣做)
  • 調用第三方組件(您的方法可能正在這樣做)
  • 改變系統的內部狀態(你的方法似乎正在這樣做)

您需要確定最終結果並對其進行測試。

這是一個非常好的問題,我也很長時間都在努力。 你的情況,你有一個功能test要測試,但功能有依賴關系- method1-3 基本上有兩種方式 -

  1. 保持代碼不變,只需測試test功能。
  2. 將依賴關系傳遞為params -

示例 -

function test(method1, method2, method3) {
 method1("#input a")
 method2("test")
 method3(1,2)
}

第二種方法可以讓您靈活地模擬方法1,2和3。

它也可以是第一種情況和第二種情況的混合,其中一些方法直接在全球范圍內使用,一些方法作為參數傳遞。

現在唯一的問題是要了解何時使用什么。 這里有一些提示 -

對於案例一

  1. 依賴關系是簡單的同步函數。 在JS中,異步函數通常會執行一些與IO相關的工作或某些非常昂貴的計算,這兩種計算都不應該妨礙測試您的test函數。
  2. 它需要輸入參數並返回輸出。
  3. 它們不會在應用程序的任何位置改變任何狀態或發送任何事件。

對於所有其他情況,您可能希望將依賴項作為參數傳遞。 例如-在這種情況下,它看起來像method1method2正在做一些DOM操作,這意味着他們應注射戲弄,其中作為method3看起來很簡單,可以從全球范圍內使用。

function (d) {
  d.method1("#input a")
  d.method2("test")
  method3(1,2)
}

如果依賴項變得太多,則可以傳遞包含所有依賴項的對象。

暫無
暫無

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

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