简体   繁体   English

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

[英]How can I provide a methods implementation using Moq?

I have an interface with a few methods. 我有几个方法的接口。 I have a default implementation of this interface. 我有这个接口的默认实现。 For the purpose of integration tests I would like to create a mock implementation that returns my custom value if one of these methods is called, and falls back to the default implementation otherwise. 出于集成测试的目的,我想创建一个模拟实现,如果调用其中一个方法,则返回我的自定义值,否则返回到默认实现。 Is it possible with Moq, or should I create a simple stub myself? 是否可以使用Moq,或者我应该自己创建一个简单的存根?

EXAMPLE

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

I'm not sure what is the condition for providing default or your specific value. 我不确定提供默认值或特定值的条件是什么。 However, it sounds like you want to set up a mock instance with Delegator . 但是,听起来您想要使用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);
}

As you can see, the Returns method is overloaded to accept a returned value( int ) or delegator representing the mocked method signature. 如您所见, Returns方法被重载以接受表示模拟方法签名的返回值( int )或委托者。 You can use Func<string, int> to replace the actual implementation - int Method(string arg) . 您可以使用Func<string, int>替换实际的实现 - int Method(string arg)

You can do this, by setting the Mock to the concrete class and using As() to retrieve the underlying IInterface , on which the setup is done. 您可以通过将Mock设置为具体类并使用As()来检索基础IInterface来完成此设置。 You can then hard cast mock.Object to invoke the underlying concrete object: 然后,您可以硬铸造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);
  }

Here's the rest of the setup I tested with, FWIW: 这是我测试的其余设置,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));
      }
   }
} 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM