我有一些带有几种方法的界面。我有这个接口的默认实现。出于集成测试的目的,我想创建一个模拟实现,如果调用其中一个方法,则返回我的自定义值,否则返回到默认实现。是否可以使用Moq,或者我应该自己创建一个简单的存根?
实施例
IInterface default = new DefaultImplementation();
var mock = new Mock<IInterface>();
mock.Setup(i => i.Method(It.IsAny<>())).Calls(p => p==0 ? return 5 : default.Method(p););
TheMethodITest(mock.Object()); //if it calls the object with 0 then it should get 5, otherwise it should call the default object
答案 0 :(得分:6)
我不确定提供默认值或特定值的条件是什么。但是,听起来您想要使用Delegator
设置模拟实例。
public void MoqCanBeSetupWithDelegator()
{
var mock = new Mock<IInterface>();
Func<string, int> valueFunction = i => i == "true" ? 1 : default(int);
mock.Setup(x => x.Method(It.IsAny<string>())).Returns(valueFunction);
Assert.Equal(1, mock.Object.Method("true"));
Assert.Equal(0, mock.Object.Method("anonymous"));
}
public interface IInterface
{
int Method(string arg);
}
如您所见,Returns
方法被重载以接受表示模拟方法签名的返回值(int
)或委托者。您可以使用Func<string, int>
替换实际的实施 - int Method(string arg)
。
答案 1 :(得分:6)
您可以通过将Mock设置为具体类并使用As()
检索完成设置的基础IInterface
来执行此操作。然后,您可以强制转换mock.Object
以调用基础具体对象:
[Test]
public void SomeTest()
{
var mock = new Mock<DefaultImplementation>().As<IInterface>();
mock.Setup(i => i.Method(It.IsAny<int>()))
.Returns<int>(p => p == 0
? 5
: ((DefaultImplementation)mock.Object).Method(p));
TheMethodITest(mock.Object);
}
这是我测试过的其余设置,FWIW:
public interface IInterface
{
int Method(int p);
}
public class DefaultImplementation : IInterface
{
public int Method(int p)
{
return 6;
}
}
[TestFixture]
public class SomeFixture
{
public static void TheMethodITest(IInterface dep)
{
for (var i = 0; i < 10; i++)
{
Debug.WriteLine("{0}:{1}",i, dep.Method(i));
}
}
}