2010-02-09 48 views
2

当测试使用Moq依赖项的类时,我希望该类为Moq方法提供参数,而不是在测试用例中自己创建参数。如何允许实现使用自己的参数调用Mock(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方法的参数。当我测试这个Messenger类时,我想模拟IMessageForwardProxy的Send方法,而不在我的测试中提供参数。我看到提供了将我的测试与实施(和复制工作)耦合的论点。

如果我想测试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

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

像这样:

mockProxy.Setup(m => m.Send(It.IsAny<IMessage>())).Returns(new ReturnMessageTwo()); 
2

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

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

这场比赛是唯一真正的当preducate传递给It.Is方法评估为true,所以这个Set只有在调用DeliverSomeOtherMessage方法时才会使用相应的返回值。

+0

难道不会和'It.IsAny ()'一样吗? – 2010-02-09 21:04:48

+0

@Jeff Cyr:不,因为那会匹配带签名Send(MessageTwo)的方法,并且此方法不存在。 – 2010-02-10 05:41:47

相关问题