2016-12-30 59 views
0

我正在使用nj4x,它有一個具有隻讀字段的類,如下所示。如何爲單元測試模擬/覆蓋只讀字段

public class MarketInformation 
    { 
    public readonly double ASK; 
    public readonly double BID; 
    public readonly double DIGITS; 
    public readonly double EXPIRATION; 
    public readonly double FREEZELEVEL; 
    } 

我正在爲編寫這些類的類和方法編寫單元測試。對於隔離/嘲笑我使用Nsubstitute和MicrosoftFakes(主要是墊片)。我想重寫這些字段,所以當它們在我的方法中被調用時,我會得到可預測的測試結果。 我爲這個類生成了填充,但它提供給我的是一個構造函數,現在允許我仍然初始化它。有沒有什麼辦法可以從這個課外設置這些領域?

+0

我對mock/fakes等知識不是很瞭解,但不是爲你的領域設置硬編碼的可預測值*模擬類內部,即你不需要通過它在外面或從外面分配它。一個模擬應該是一個你正在嘲笑的抽象的實現,就像實現中的「真實」類一樣。 –

+0

@ rory.ap實現模擬是一個獨立的想法,但是,我正在使用框架進行模擬和隔離。實現模擬需要抽象/接口類。但是這些在這裏不可用。 –

+1

您需要創建一個可以模擬的接口。成員需要是「虛擬」的。 (NSubstitute只能與類的虛擬成員一起工作,因此類中的任何非虛擬代碼都將實際執行!)[參考](http://nsubstitute.github.io/help/creating-a-substitute/) – NtFreX

回答

0

您可能需要使用自己的get屬性創建一個包裝類來存根或填充它。如果您想使用存根(未顯示),您可以創建自己的界面。

public class MarketInformationWrapper : MarketInformation 
{ 
    ... 
    public double Ask 
    { 
     get { return ASK; } 
    } 
    ... 
} 
+0

我懷疑這對我沒有任何好處。這隻有當我可以將對象傳入測試的類或方法時才起作用。 我想要的是墊片做的事情。 就像我爲班級假人創建一個墊片,說shimDummy。那麼我只能說 shimDummy.AllInstances。Ask =(Dummy)=> 5; 這樣,每當它被調用時我都會得到5。 –

2

這是不漂亮,但如果你有機會到需要進行修改的情況下,你可以使用the SetField method of the PrivateObject class。類是PrivateObject類是MS單元測試框架的一部分。

例如,考慮類:

public class ClassWithReadOnly 
{ 
    public readonly string Foo; 

    public ClassWithReadOnly() 
    { 
     Foo = "bar"; 
    } 
} 

您可以設置只讀場像這樣:

var test = new ClassWithReadOnly(); 
Console.WriteLine("Before Foo == '{0}'", test.Foo); 
var po = new PrivateObject(test); 
po.SetField("Foo", "oof"); 
Console.WriteLine("After Foo == '{0}'", test.Foo); 

輸出將是:

美孚之前= ='bar'

After Foo =='oof'