代码之家  ›  专栏  ›  技术社区  ›  Josh Smeaton

如何允许实现使用自己的参数调用模拟(moq)方法?

  •  2
  • Josh Smeaton  · 技术社区  · 14 年前

    当测试使用moq依赖项的类时,我希望该类为moq方法提供参数,而不是在测试用例中自己创建参数。

    我有一个接口,它有一个方法,它接受一个参数。

    public interface IMessageForwardProxy
    {
        IMessage Send(IMessage request);
    }
    

    我有一个类,根据类上调用的方法,用许多不同的参数调用此方法。例如:

    public class Messenger 
    {
        private IMessageForwardProxy _link;
    
        public Messenger(IMessageForwardProxy proxy) { _link = proxy; }
    
        public bool DeliverSomeMessage() {
            IMessage m1 = new MessageOne();
            var response = _link.Send(m1);
            return response.Succeeded;
        }
    
        public bool DeliverSomeOtherMessage() {
            IMessage m2 = new MessageTwo();
            var response = _link.Send(m2);
            return response.Succeeded;
        }
    }
    

    现在如您所见,messenger类负责创建传递给接口的send方法的参数。当我测试这个信使类时,我想模拟IMessageForwardProxy的发送方法,而不在测试中提供参数。我把提供参数看作是将测试耦合到实现(和复制工作)上。

    如果我想在messenger类上测试deliversomeothermessage方法,我将如何模拟IMessageForwardProxy?

    [Test]
    public void TestDeliverSomeOtherMessage() {
        var mockProxy = new Mock<IMessageForwardProxy>();
    
        // This is what I want to avoid, since the method I'm testing creates this argument
        IMessage m2 = new MessageTwo(); 
        mockProxy.Setup(m => m.Send(m2)).Returns(new ReturnMessageTwo());
    
        // Can I do something like this instead? Define the signature, but not the param?
        mockProxy.Setup(m => m.Send(typeof(IMessage))).Returns(new ReturnMessageTwo());
    
        var messenger = new Messenger(mockProxy.Object);
        Assert.True(messenger.DeliverSomeOtherMessage());
    
    }
    
    2 回复  |  直到 14 年前
        1
  •  2
  •   Jeff Cyr    14 年前

    你可以使用 It.IsAny<IMessage>()

    这样地:

    mockProxy.Setup(m => m.Send(It.IsAny<IMessage>())).Returns(new ReturnMessageTwo());
    
        2
  •  2
  •   Mark Seemann    14 年前

    在这种情况下,您可以使用 It.Is<IMessage> 期望匹配:

    mockProxy.Setup(m => m.Send(It.Is<IMessage>(m => m is MessageTwo)))
        .Returns(new ReturnMessageTwo());
    

    只有当Preducte传递给它时,此匹配才为true.is方法的计算结果为true,因此只有在调用DeliverSomeOtherMessage方法时才会使用此设置和相应的返回值。