![](/img/trans.png)
[英]Is there a standard method for unit testing code where dependencies do not implement interfaces?
[英]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.