我无法理解如何测试自定义属性,我需要模拟内部状态属性。属性添加了扩展方法。
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
实例才能做任何事情,但我不知道如何做。我不知道如何重构它以使其可测试。