如何允许实现使用自己的参数调用 Mock (Moq) 方法?

发布于 2024-08-20 21:49:26 字数 1580 浏览 3 评论 0原文

当测试使用 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 方法的参数。当我测试这个 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());

}

When testing a class that uses a Moq dependency, I'd like the class to supply the arguments to a Moq method, rather than creating the arguments myself in the test case.

I have an interface, that has one method, which takes one argument.

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

I have a class that calls this method with a number of different arguments depending on the method called on the class. For instance:

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

Now as you can see, the Messenger class is responsible for creating the arguments that are passed to the Send method of the interface. When I'm testing this Messenger class, I would like to Mock the IMessageForwardProxy's Send method, without providing the argument in my tests. I see providing the argument as coupling my tests to the implementation (and duplicating work).

If I want to test the DeliverSomeOtherMessage method on the Messenger class, how would I mock the 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());

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

海之角 2024-08-27 21:49:26

您可以使用 It.IsAny()

像这样:

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

You can use It.IsAny<IMessage>()

Like this:

mockProxy.Setup(m => m.Send(It.IsAny<IMessage>())).Returns(new ReturnMessageTwo());
甜点 2024-08-27 21:49:26

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

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

仅当传递给 It.Is 方法的 preducate 计算结果为 true 时,此匹配才为 true,因此此 Setup 和相应的返回值仅当您调用 DeliverSomeOtherMessage 方法时才会使用。

In this case, you can use the It.Is<IMessage> expectation match:

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

This match is only true when the preducate passed to the It.Is method evaluates to true, so this Setup and corresponding return value will only be used when you invoke the DeliverSomeOtherMessage method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文