【发布时间】:2018-08-01 12:21:08
【问题描述】:
我无法弄清楚如何测试需要模拟内部状态属性的自定义属性。 Attribute 增加了一个扩展方法。
Configuration 属性是静态属性,在实践中可以正常工作,但在运行并行测试时不起作用。
我所拥有的一些伪代码:
public class MyAttribute : Attribute
{
// Store a complex object that cannot be passed into constructor
private static IConfiguration _configuration;
public static IConfiguration
{
get {
if (_configuration == null)
_configuration = new Configuration();
return _configuration;
}
set {
_configuration => value;
}
}
public MyAttribute(string foo)
{
// foo is a simple type
}
}
public static class MyExtensionClass
{
public static Task<T> DoSomething<T>(this Delegate method, params object[] args)
{
DoSomethingWithConfiguration(MyAttribute.Configuration);
// or if I make Configuration an instance property
MethodInfo mi = method.GetMethodInfo();
MyAttribute attr = mi.GetCustomAttribute<MyAttribute>();
DoSomethingWithConfiguration(attr.Configuration);
return ....
}
}
一个示例测试:
public class TestClass
{
[MyAttribute(foo="bar")]
public int Add(int x, int y)
{
return x + y;
}
delegate int AddDelegate(int x, int y);
[Fact]
public void TestSomething()
{
Delegate d = new AddDelegate(Add);
Mock<IConfiguration> mockConfig = new Mock<IConfiguration>();
mockConfig.Setup(.....); // set up mocked interface
// ** Need to inject mock into Attribute class somehow
// ** This doesn't work with parallel test runs **
MyAttribute.Configuration = mockConfig.Object;
var result = d.DoSomething<int>(1, 2);
}
}
如果我模拟 IConfiguration 并设置静态属性,那么当我的测试并行运行时,该值将被覆盖并且测试随机失败。我知道这是错误的做事方式。具体来说,Configuration 类间接连接到服务器(通过工厂方法),因此需要模拟它。
我想我需要在 MyAttribute 实例执行任何操作之前以某种方式获取它,但我不知道如何。我被困在如何重构它以使其可测试。
【问题讨论】:
标签: c# unit-testing .net-core moq xunit.net