嘲弄靜態方法
回答
像Moq或Rhinomocks這樣的模擬框架只能創建對象的模擬實例,這意味着模擬靜態方法是不可能的。
您還可以search Google瞭解更多信息。
@ Pure.Krome:不錯的反響,但我會添加一些細節
@Kevin:你必須選擇取決於你能夠給代碼的變化的解決方案。
如果你可以改變它,一些依賴注入使代碼更加可測試。 如果你不能,你需要一個很好的隔離。
使用免費的嘲諷框架(Moq,RhinoMocks,NMock ...),您只能嘲笑委託,接口和虛擬方法。因此,對於靜態的,封閉和非虛擬方法,你有3個解決方案:
我推薦Moles,因爲它是免費,高效的並且使用像Moq這樣的lambda表達式。只有一個重要的細節:痣提供存根,而不是嘲笑。所以,你仍然可以使用起訂量爲接口和代表;)
模擬:實現一個接口,允許動態設置,返回/異常的具體方法扔值的能力,並提供能力的類檢查是否有特定的方法被調用/未被調用。
存根(stub):就像一個模擬類,除了它不提供驗證方法被調用/未調用的能力。
有可能在.NET中排除MOQ和任何其他嘲諷庫。您必須右鍵單擊包含要模擬的靜態方法的程序集解決方案資源管理器,然後選擇添加僞造程序集。接下來,你可以自由地模擬這是程序集靜態方法。
假設你想模擬System.DateTime.Now
靜態方法。比如這樣做:
using (ShimsContext.Create())
{
System.Fakes.ShimDateTime.NowGet =() => new DateTime(1837, 1, 1);
Assert.AreEqual(DateTime.Now.Year, 1837);
}
你對每個靜態屬性和方法都有類似的屬性。
發現此問題的人的警告:MS Fakes僅內置於Visual Studio 2012+ Premium/Ultimate中。您可能無法將其整合到持續集成鏈中。 – thomasb 2015-06-05 16:26:30
這應該是被接受的答案。 MS現在帶有墊片的假貨使得它很可能嘲笑靜態方法。 – Jez 2016-03-10 11:47:52
非常小心使用MS假貨!假貨是一個重定向框架,它的使用很快導致糟糕的架構。只有在絕對必要時才使用Fakes,以攔截對第三方或(非常)遺留庫的調用。最好的解決方案是創建一個帶有接口的類封裝器,然後通過構造器注入或通過注入框架傳遞接口。模擬接口,然後將其傳遞到測試中的代碼中。如果可能的話,遠離假貨。 – 2017-01-17 17:53:26
我知道這有點晚了,但是這個迂迴的解決方案讓我嘲笑使用Moq的靜態方法。
爲此,我創建了一個類(我們稱之爲Placeholder
),其中一個方法稱爲靜態方法StaticClass.GetFile
。
public class Placeholder{
//some empty constructor
public File GetFile(){
File f = StaticClass.GetFile(filePath);
return f;
}
}
然後,而不是調用foo
StaticClass.GetFile
,我創建的Placeholder
一個實例並稱爲GetFile
功能。
public void foo(string filePath)
{
Placeholder p = new Placeholder();
File f = p.GetFile(filePath);
}
現在,在單元測試,而不是試圖嘲笑StaticClass.GetFile
,我可以嘲笑從Placeholder
類的非靜態GetFile
方法。
缺少界面以及如何模擬 – 2018-02-19 11:04:44
我一直在玩一個重構靜態方法的概念來調用委託,您可以在外部爲測試目的設置一個委託。
這不會使用任何測試框架,而是一個完全定製的解決方案,但重構不會影響您的調用者的簽名,因此它將是一個相對安全的。
爲此,您需要訪問靜態方法,因此它不適用於任何外部庫,如System.DateTime
。
繼承人一個例子我一直在玩的地方,我創建了幾個靜態方法,一個返回類型接受兩個參數和一個沒有返回類型的泛型。
主要靜態類:
public static class LegacyStaticClass
{
// A static constructor sets up all the delegates so production keeps working as usual
static LegacyStaticClass()
{
ResetDelegates();
}
public static void ResetDelegates()
{
// All the logic that used to be in the body of the static method goes into the delegates instead.
ThrowMeDelegate = input => throw input;
SumDelegate = (a, b) => a + b;
}
public static Action<Exception> ThrowMeDelegate;
public static Func<int, int, int> SumDelegate;
public static void ThrowMe<TException>() where TException : Exception, new()
=> ThrowMeDelegate(new TException());
public static int Sum(int a, int b)
=> SumDelegate(a, b);
}
單元測試(的xUnit和Shouldly)
public class Class1Tests : IDisposable
{
[Fact]
public void ThrowMe_NoMocking_Throws()
{
Should.Throw<Exception>(() => LegacyStaticClass.ThrowMe<Exception>());
}
[Fact]
public void ThrowMe_EmptyMocking_DoesNotThrow()
{
LegacyStaticClass.ThrowMeDelegate = input => { };
LegacyStaticClass.ThrowMe<Exception>();
true.ShouldBeTrue();
}
[Fact]
public void Sum_NoMocking_AddsValues()
{
LegacyStaticClass.Sum(5, 6).ShouldBe(11);
}
[Fact]
public void Sum_MockingReturnValue_ReturnsMockedValue()
{
LegacyStaticClass.SumDelegate = (a, b) => 6;
LegacyStaticClass.Sum(5, 6).ShouldBe(6);
}
public void Dispose()
{
LegacyStaticClass.ResetDelegates();
}
}
- 1. 在JUnit測試中使用JMockit多次嘲弄靜態方法
- 2. 當使用EasyMock + PowerMock嘲弄靜態方法時發生java.lang.ExceptionInInitializerError
- 3. JustMock:嘲弄靜態方法調用不工作
- 4. Powermockito:嘲諷靜態方法
- 5. 嘲諷靜態方法
- 6. 嘲笑靜態方法嘲諷
- 7. 用PowerMockito部分嘲弄靜態
- 8. 嘲弄:嘲弄publicaly覆蓋保護的方法
- 9. 替代嘲笑一個靜態方法
- 10. 嘲笑其他靜態方法
- 11. 使用PowerMockito嘲笑靜態方法
- 12. jmock嘲笑一種靜態方法
- 13. 嘲笑Mockito的靜態方法
- 14. 嘲笑使用Rhino.Mocks的靜態方法
- 15. 嘲弄一般的方法調用
- 16. PHPunit方法嘲弄不起作用
- 17. PHPUnit的嘲弄方法返回null
- 18. 在C#中嘲弄非虛擬方法#
- 19. 單元測試方法嘲弄的IList
- 20. 在犀牛嘲弄嘲弄拉姆達
- 21. 在單元測試環境中嘲弄/僞造靜態函數
- 22. 嘲弄與andReturn
- 23. 靜態靜態方法?
- 24. PHP:錯誤嘲弄
- 25. 用PowerMockito嘲弄LocalDateTime
- 26. 用Moq嘲弄HttpContextBase
- 27. 無法通過嘲弄一個jmockit私有方法
- 28. 嘲笑Util類使用gmock的靜態方法
- 29. 嘲笑多次調用的靜態方法
- 30. 如何輕鬆地嘲笑Java中的靜態方法(jUnit4)
作爲更新此。痣現在被稱爲Fakes,並內置到Visual Studio 2012中:http://msdn.microsoft.com/en-us/library/hh549175.aspx – gscragg 2013-11-27 21:55:27
在Moles中,你可以驗證一個方法是否被調用,只是添加一個布爾變量和在存根函數內設置它也可以驗證調用此工作週期中的所有參數。 – mart 2013-12-20 13:28:34
嗨Jeco ...我從你上面的答案中得到了一些想法。您可以請回答一個問題在http://stackoverflow.com/questions/27621085/moles-shims-frameworks-other-than-introduced-by-microsoft – 2014-12-24 12:20:14