在我的单元测试中尝试遵循DRY(不要重复自己)原则我试图创建一个通用单元测试,它将对几个返回共享相同接口的对象的方法执行相同的测试。但是,我似乎无法找到一种方法来为泛型方法中的方法创建一个mock.Setup。示例如下:
以下是类实现:
public class RootClass
{
public Foo Foo { get; set; }
}
public class Foo
{
public Bar1 Method1(int x)
{
var bar = new Bar1();
// do stuff //
return bar;
}
public Bar2 Method2(string str)
{
var bar = new Bar2();
// do stuff //
return bar;
}
}
public interface IBar
{
string Message { get; set; }
bool Success { get; set; }
Exception ex { get; set; }
}
public class Bar1 : IBar
{
public string Result { get; set; }
public Exception ex { get; set; }
public string Message { get; set; }
public bool Success { get; set; }
}
public class Bar2 : IBar
{
public int Result { get; set; }
public Exception ex { get; set; }
public string Message { get; set; }
public bool Success { get; set; }
}
以下是测试实施:
private static RootClass systemUnderTest;
private static Mock<IFoo> FooMock;
[TestInitialize]
public void Setup()
{
FooMock = new Mock<IFoo>();
systemUnderTest = new RootClass();
systemUnderTest.Foo = FooMock.Object;
}
[TestMethod]
public void Method1_Bar1SuccessIsTrue()
{
//FooMock.Setup(x => x.Method1(It.IsAny<int>())).Returns(new Bar1); <~~~~This is the Moq Setup I would like to move into the generic method
AssertBarSuccessIsTrue<int, Bar1>(systemUnderTest.Bar1, FooMock.Object.Bar1);
}
[TestMethod]
public void Method2_Bar2SuccessIsTrue()
{
//FooMock.Setup(x => x.Method2(It.IsAny<string>())).Returns(new Bar2);
AssertBarSuccessIsTrue<string, Bar2>(systemUnderTest.Bar2, FooMock.Object.Bar2)
}
private void AssertBarSuccessIsTrue<PARAM, BAR>(Func<PARAM, BAR> f, Func<PARAM, IBAR> task) where BAR : IBAR where PARAM : new()
{
FooMock.Setup(x => task); <~~~Throws an ArgumentException; no doubt because of the missing lambda expression.
PARAM parameter = new PARAM();
BAR bar = f.Invoke(parameter);
Assert.IsTrue(bar.Success);
}
我试图通过多次尝试来完成这项工作,包括为lambda表达式创建一个参数,为It.IsAny&lt;&gt;()表达式创建一个参数,为测试中的指定方法创建委托。但是,每次尝试都会产生编译器错误或引发运行时异常。
如果我在每个测试中进行设置,我可以创建通用测试(如注释掉的.Setup行中所示)。但是,是否有人知道如何将该设置行移动到通用方法中?我知道它只有一行,但在我看来这应该是可能的。