如何使用Moq提供方法实现?

时间:2014-06-11 14:49:37

标签: c# nunit integration-testing moq

我有一些带有几种方法的界面。我有这个接口的默认实现。出于集成测试的目的,我想创建一个模拟实现,如果调用其中一个方法,则返回我的自定义值,否则返回到默认实现。是否可以使用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

2 个答案:

答案 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));
      }
   }
}