簡體   English   中英

具有依賴性的單元測試方法(無接口)

[英]Unit testing methods with dependencies (with no interfaces)

從單元測試開始,我想知道如何測試我們的舊代碼,看起來像這樣:

public Player DetermineWinner(Player a, Player b)
{
   if(a.Age>b.Age)
    ....  
   ///few more conditions checking properties of both players
}

class Player
{
  public Player (DBConnection c, world w, DateTime logTime)
  {} //not easy to mock...
}

怎么嘲笑呢? 我知道,如果播放器實現了一個接口,我可以簡單地創建一個模擬並以所需的值在單元測試中將其傳遞,但​​實際情況並非如此。 Player類使用各種參數實例化,因此我不能在單元測試期間簡單地創建一個實例並將其傳遞-它取決於各種外部對象。 我需要模擬Player對象並同時設置其屬性,以便測試是確定性的。 最佳的開始方法是什么?

下次是否應該使用接口來解耦?

您可以使用諸如Typemock之類的框架對代碼進行單元測試而無需更改代碼,該框架使您無需添加接口即可模擬具體的依賴關系,並且在選擇要模擬的類時(在這種情況下為“ Player”,Typemock也會自動模擬其中的所有依賴項)。

在給定的示例中:

public class UnitTest1
    {
        [TestMethod]
        public void TestDetermineWinner_B_IsTheWinner()
        {
            var P1 = Isolate.Fake.Instance<Player>();
            var P2 = Isolate.Fake.Instance<Player>();

            Isolate.WhenCalled(() => P1.Age).WillReturn(0);
            Isolate.WhenCalled(() => P2.Age).WillReturn(1);

            var result = new ClassUnderTest().DetermineWinner(P1, P2);

            Assert.AreEqual(P2, result);
        }
    }
    public class ClassUnderTest
    {
        public Player DetermineWinner(Player a, Player b)
        {
            if (a.Age > b.Age) { return a; }
            return b;
        ///few more conditions checking properties of both players
        }
    }
    public class Player
    {
        public Player(DbConnection c, world w, DateTime logTime)
        { } //not easy to mock...

        public int Age { get; internal set; }
    }

我認為您不了解嘲笑的真正含義。

模擬對象與該類的“真實”實現無關 它只是“看起來”像該類的對象。

但是您(分別是模擬框架)可以控制該對象的行為。 好吧,除非該字段是私有的 (請參見此處 )。 所以:當您的Player字段不是私有字段時,您就不會有問題。

沒有模擬框架-您真的無法做很多事情。 如果有的話,您可能正在模擬作為被測試類的構造函數的參數所需的所有對象。

換句話說:最后,您需要類“ X”的某個對象“ x”; 當使用“真實”類“ X”給您帶來很多麻煩時,則必須用看起來像“ X”的東西來代替它。

最壞的情況是,您可能有兩個不同的X類版本; 但這會使事情變得復雜。

暫無
暫無

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

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