简体   繁体   中英

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?

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 .

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. You can use Func<string, int> to replace the actual implementation - 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. You can then hard cast mock.Object to invoke the underlying concrete 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:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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