使用moq模拟静态类

mah*_*rma 6 .net c# nunit moq

我在NUnit的帮助下编写单元测试用例并且有一些静态类需要模拟来运行测试用例,所以我们可以在MOQ模拟框架的帮助下模拟静态类吗?

请建议如果有人有想法.

Aar*_*rts 9

有两种方法可以实现这一点 - 正如PSGuy所说,您可以创建一个代码可以依赖的接口,然后实现一个简单地调用静态方法或任何其他日志记录实现(如NLog)的具体方法.这是理想的选择.除此之外,如果你有很多代码调用需要测试的静态方法,你可以重构静态方法来进行模拟.

假设您的静态类看起来像这样:

public static class AppLog
{
    public static void LogSomething(...) { ... }
}
Run Code Online (Sandbox Code Playgroud)

您可以引入一个公共静态属性,它是上述接口的一个实例.

public static class AppLog
{
    public static ILogger Logger = new Logger();

    public static void LogSomething(...)
    {
        Logger.LogSomething(...);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在可以测试任何依赖于此静态方法的代码.

public void Test()
{
    AppLog.Logger = Substitute.For<ILogger>(); // NSubstitute

    var logMock = new Mock<ILogger>();         // Moq
    AppLog.Logger = logMock.Object;            // Moq 

    SomeMethodToTest();

    AppLog.Logger.Recieved(1).LogSomething(...); // NSubstitute

    logMock.Verify(x => x.LogSomething(...));    // Moq
}
Run Code Online (Sandbox Code Playgroud)

  • 您可以使用公共 setter 方法轻松地将其设为私有。这也能达到同样的效果。只需要一种方法来设置它,以便它可以被嘲笑。 (2认同)