2010-03-09 94 views
2

這似乎是一個很容易的問題,但我似乎無法找到關鍵字來影響我的搜索。moqing靜態方法調用c#庫類

我試圖通過嘲笑此方法調用內的所有對象進行單元測試。我能夠這樣做的都是我自己創作的,除了這一個:

public void MyFunc(MyVarClass myVar) 
{ 
    Image picture; 
    ... 

    picture = Image.FromStream(new MemoryStream(myVar.ImageStream)); 

    ... 
} 

FromStream從圖像類的靜態調用(C#的一部分)。所以我怎麼能重構我的代碼來嘲笑這一點,因爲我真的不想提供一個圖像流到單元測試。

回答

1

您可以將靜態函數包裝到Func類型屬性中,該屬性可以通過單元測試使用模擬或存根來設置。

public class MyClass 
{ 
    .. 

    public Func<Image, MemoryStream> ImageFromStream = 
            (stream) => Image.FromStream(stream); 


    public void MyFunc(MyVarClass myVar) 
    { 
     ... 

     picture = ImageFromStream(new MemoryStream(myVar.ImageStream)); 

     ... 
    } 


    .. 
} 
+0

我覺得像包裝到一個界面的想法,如果我有多個靜態調用實例通過我的代碼,此解決方案不能很好地擴展。 我將不得不爲每個靜態調用創建一個函數。有沒有辦法模擬庫類的靜態方法? – Joe 2010-03-09 06:41:26

+0

您只需要爲不同的靜態方法創建一個屬性,因爲您可以重複使用它們。我相信TypeMock可以使用一些IL編織來嘲弄靜態方法,但它不是免費的。解耦代碼是可測試的,在C#中恐怕需要很多工作。 – tarn 2010-03-09 06:47:41

+0

經過一番思考,提供的界面和功能解決方案都很混亂,但是這個功能解決方案比創建一個新界面和類僅僅嘲弄一個靜態功能花費更少的線。所以我正在用這個。感謝所有的答案。 – Joe 2010-03-10 01:35:44

3

您可以創建一個IImageLoader接口。 「正常」實現只是調用Image.FromStream,而您的單元測試版本可以做任何您需要的操作。

+0

這將意味着我不得不爲每一個靜態方法調用我會想辦法讓不同類別的接口。 我希望有一個更優雅的方式來做到這一點...... – Joe 2010-03-09 06:37:44

+1

不,沒有優雅的方式來解決這個靜態編譯語言沒有運行時幫助。有一種方法可以通過訪問分析CLR API(非常複雜)來完成此操作。這就是TypeMock的工作原理 – CVertex 2010-03-09 06:46:08

+1

除了CVertex使用TypeMock的解決方案之外,確實沒有辦法。靜態方法和單元測試並不能很好地結合在一起。 – 2010-03-09 06:47:53

2

Moq和大多數其他模擬框架不支持嘲笑靜態方法。然而,TypeMock確實支持嘲笑靜態方法,如果您願意購買它,可能會對您感興趣。否則,你將不得不重構,以便可以模擬一個接口...

+0

MSR的痣也在這個空間中發揮作用 – 2010-03-10 13:47:25

1

這可以通過Moles,一個Visual Studio 2010電動工具來實現。該Moles代碼應該是這樣的:

// replace Image.FromStream(MemoryStream) with a delegate 
MImage.FromStreamMemoryStream = stream => null;