我是单元测试的新手,我正在尝试在一个静态类中模拟静态方法,我已经读到您无法做到这一点,但是我正在寻找一种解决方法。
>我不能修改代码,并且要在不静态的情况下执行相同的功能,这不是一个选择,因为他们检查测试的代码覆盖率,而且我至少需要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
}
我的问题是此方法在控制器内部,该控制器声明带有响应的var,并据此重定向用户。
答案 0 :(得分:0)
对于这类问题,可能有更好的解决方案......取决于你能摆脱什么。
我最近在编写了一个静态实用程序类后自己遇到了这个问题,该类本质上用于创建 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);
答案 1 :(得分:-1)
如果您无法修改代码,那么我认为不可能使用基于动态代理的库(例如NSubstitute)解决此问题。这些库使用inheritance to intercept members on classes,静态成员和非虚拟成员都无法使用。
我建议尝试Fakes。该页面上的示例之一涉及存根DateTime.Now
。
其他可以模拟静态成员的替代方法包括TypeMock和Telerik JustMock。