嘲弄静态方法
回答
像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