繁体   English   中英

NSubstitute Mock 静态类和静态方法

[英]NSubstitute Mock static class and static method

我是单元测试的新手,我正在尝试模拟静态类中的静态方法。 我已经读到你不能这样做,但我正在寻找一种方法来解决这个问题。

我无法修改代码,并且在不静态的情况下制作相同的功能不是一种选择,因为它们会检查测试的代码覆盖率,而我至少需要 90%。
我已经尝试模拟它使用的变量,但它不起作用。

public static class MyClass
{
    public static response MyMethod(HttpSessionStateBase Session, 
        otherVariable, stringVariable)
    {
        //some code
    }
}

public ActionResult MyClassTested()
{
    var response = MyClass.MyMethod(Session);
    //more code
}

我的问题是这个方法在一个控制器中,该控制器声明了一个带有响应的变量,并据此重定向用户。

如果您无法修改代码,那么我认为无法使用基于 DynamicProxy 的库(如 NSubstitute)来解决此问题。 这些库使用继承来拦截类上的成员,这对于静态和非虚拟成员是不可能的。

我建议尝试假货 该页面上的示例之一涵盖了存根DateTime.Now

其他可以模拟静态成员的替代方案包括 TypeMock 和 Telerik JustMock。

相关问题: https : //stackoverflow.com/q/5864076/906

这类问题可能有更好的解决方案……这取决于你能摆脱什么。

我最近在编写了一个静态实用程序类后自己遇到了这个问题,该类基本上用于创建 Guid 格式的各种截断。 在编写集成测试时,我意识到我需要控制从该实用程序类生成的随机 Id,以便我可以故意将此 Id 发送给 API,然后对结果进行断言。

我当时采用的解决方案是从静态类提供实现,但从非静态类中调用该实现(包装静态方法调用),我可以在 DI 容器中注册和注入。 这个非静态类将是主要的主力,但在我需要从另一个静态方法调用这些方法的情况下,静态实现将可用(例如,我已经编写了很多集成设置代码作为 IWevApplicationFactory 上的扩展,并使用静态实用程序创建数据库名称)。

在代码中,例如

// my static implementation - only use this within other static methods when necessary. Avoid as much as possible.
public static class StaticGuidUtilities 
{
    public static string CreateShortenedGuid([Range(1, 4)] int take)
    {
        var useNumParts = (take > 4) ? 4 : take;
        var ids = Guid.NewGuid().ToString().Split('-').Take(useNumParts).ToList();
        return string.Join('-', ids);
    }
}


// Register this abstraction in the DI container and use it as the default guid utility class
public interface IGuidUtilities
{
    string CreateShortenedGuid([Range(1, 4)] int take);
}

// Non-static implementation
public class GuidUtitlities : IGuidUtilities
{
    public string CreateShortenedGuid([Range(1, 4)] int take)
    {
        return StaticGuidUtilities.CreateShortenedGuid(take);
    }
}

----

// In the tests, I can use NSubstitute...
// (Doesn't coding to the abstraction make our lives so much easier?)
var guidUtility = Substitute.For<IGuidUtilities>();
var myTestId = "test-123";
guidUtility.CreateShortenedGuid(1).Returns(myTestId);

// Execute code and assert on 'myTestId' 
// This method will call the injected non-static utilty class and return the id
var result = subjectUndertest.MethodUnderTest();

// Shouldly syntax
result.Id.ShouldBe(myTestId);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM