我正在为单个接口上定义的一系列类似方法编写单元测试(这是重构的前提)。我发现类似的代码出现在多种方法中:
// Each line here shows up in a different test method.
mock.Setup(m => m.MethodA()).Returns(() => true);
mock.Setup(m => m.MethodB()).Returns(() => true);
mock.Setup(m => m.MethodC()).Returns(() => true);
我想创建一个单一的方法,我可以传递给要测试的方法,但不知道如何做到这一点。我想要一些看起来像这样的东西:
// testMethod is some method defined on IMyInterface.
private Mock<IMyInterface> SetupMockObject(Func<bool> testMethod)
{
var mock = new Mock<MyInterface>();
mock.Setup(m => m.testMethod()).Returns(() => true);
return mock;
}
对此方法的调用将类似于:
var configuredMockObject = SetupMockObject(MethodA);
这可能吗?
编辑:表达式树似乎是我需要的 - 以前我没有得到你可以传递lambda表达式的概念。我已经粘贴了下面的解决方案,因为我花了一点时间来解决这个问题,尽管dBurner和Servy的答案都证明是有帮助的。
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Moq.Language.Flow;
using System;
using System.Linq.Expressions;
namespace ExampleTest
{
[TestClass]
public class TestClass
{
private Mock<IMyInterface> _mock;
private interface IMyInterface
{
bool MethodA();
bool MethodB();
}
private ISetup<IMyInterface, bool> SetupMockObject(Expression<Func<IMyInterface,bool>> lambda)
{
var mockSetup = _mock.Setup(lambda);
return mockSetup;
}
[TestInitialize]
public void Setup()
{
_mock = new Mock<IMyInterface>();
}
[TestMethod]
public void TestMethodA()
{
SetupMockObject(i => i.MethodA()).Returns(true);
// Proceed with act and assert.
}
[TestMethod]
public void TestMethodB()
{
SetupMockObject(i => i.MethodB()).Returns(true);
// Proceed with act and assert.
}
}
}
答案 0 :(得分:2)
传递给它的lambda需要有一个mocked类型的参数,而你当前的参数接受一个无参数的委托:
public static Mock<MyInterface> SetupMockObject<T>(
Func<MyInterface, bool> testMethod)
{
var mock = new Mock<MyInterface>();
mock.Setup(testMethod).Returns(() => true);
return mock;
}
这允许你写:
var mock = SetupMockObject(m => m.MethodA());
并让代码等同于
var mock = new Mock<MyInterface>();
mock.Setup(m => m.MethodA()).Returns(() => true);
答案 1 :(得分:1)
您可以使用表达式树。您的CommonTest
方法应该有一个Expression<Func<bool>>
参数。
使用此参数类型,您可以获取方法名称。在此之后,您应该构建另一个表示m => m.MethodFromParameter
的表达式。