如何模拟 HttpResponseBase.End()?

发布于 2024-07-29 06:37:41 字数 727 浏览 1 评论 0原文

我正在使用 Moq 创建 HttpResponseBase 的模拟对象。 我需要能够测试 HttpResponseBase.End() 在我的库中被调用。 为此,我在调用之前指定了一些文本,在调用之后指定了一些文本。 然后我检查 HttpResponseBase.Output 中是否仅存在调用 End() 之前的文本。

问题是,我不知道如何模拟 HttpResponseBase.End() 以便它停止处理,就像在 ASP.NET 中那样。

public static HttpResponseBase CreateHttpResponseBase() {
    var mock = new Mock<HttpResponseBase>();
    StringWriter output = new StringWriter();

    mock.SetupProperty(x => x.StatusCode);
    mock.SetupGet(x => x.Output).Returns(output);
    mock.Setup(x => x.End()) /* what do I put here? */;
    mock.Setup(x => x.Write(It.IsAny<string>()))
        .Callback<string>(s => output.Write(s));

    return mock.Object;
}

I'm using Moq to create a mock object of HttpResponseBase. I need to be able to test that HttpResponseBase.End() was called in my library. To do this, I specify some text before the call and some text after. Then I check that only the text before the call to End() is present in HttpResponseBase.Output.

The problem is, I can't figure out how to mock HttpResponseBase.End() so that it stops processing, like it does in ASP.NET.

public static HttpResponseBase CreateHttpResponseBase() {
    var mock = new Mock<HttpResponseBase>();
    StringWriter output = new StringWriter();

    mock.SetupProperty(x => x.StatusCode);
    mock.SetupGet(x => x.Output).Returns(output);
    mock.Setup(x => x.End()) /* what do I put here? */;
    mock.Setup(x => x.Write(It.IsAny<string>()))
        .Callback<string>(s => output.Write(s));

    return mock.Object;
}

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

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

发布评论

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

评论(1

骑趴 2024-08-05 06:37:41

我有点不清楚你想要实现什么,但从你的描述来看,听起来你正在试图让你的抽象表现得像一个特定的实现。 换句话说,因为 HttpResponse.End() 有一定的行为,你希望你的 Mock 也有同样的行为吗?

一般来说,用 Moq 来做到这一点并不是特别容易,因为它没有有序期望的概念(与 RhinoMocks 不同)。 不过,有一个对此的功能请求

您也许可以使用回调并设置 End 方法来切换确定 Mock 的任何进一步行为的标志,但这不会特别漂亮。 我正在考虑这样的事情:

bool ended = false;
var mock = new Mock<HttpResponseBase>();
mock.Setup(x => x.End()).Callback(() => ended = true);
// Other setups involving 'ended' and Callbacks

然后让所有其他设置根据 end 是 true 还是 false 来进行双重实现。

这将是非常丑陋的,所以我现在会认真地重新考虑我的选择。 您至少可以采取两个方向:

  1. 制作 HttpResponseBase 的 Fake 实现,而不是使用 Moq。 听起来您期望实现这种特定的行为,因此具有嵌入式逻辑的测试替身听起来是一个更好的选择。 简而言之,Fake 是一个测试替身,可以包含模仿预期生产实现的半复杂逻辑。 您可以在优秀的 xUnit 测试模式中阅读有关 Fakes 和其他测试替身的更多信息书。
  2. 重新考虑您最初的假设。 在我看来,您将客户端与 HttpResponseBase 的特定行为紧密联系在一起,因此您可能违反了里氏替换原则。 然而,我可能是错误的,因为称为“End”的方法具有超出纯粹语义的某些含义,但我个人仍然会考虑是否可以进行更好的设计。

It is a bit unclear to me what it is you are trying to achieve, but from your description, it sounds like you are attempting to get your Abstraction to behave like a particular implementation. In other words, because HttpResponse.End() has a certain behavior, you want your Mock to have the same behavior?

In general, that is not particularly easy to do with Moq, since it has no concept of ordered expectations (unlike RhinoMocks). There is, however, a feature request for it.

You might be able to use a Callback together with setting up the End method to toggle a flag that determines any further behavior of the Mock, but it's not going to be particularly pretty. I'm thinking about something like this:

bool ended = false;
var mock = new Mock<HttpResponseBase>();
mock.Setup(x => x.End()).Callback(() => ended = true);
// Other setups involving 'ended' and Callbacks

Then have all other Setups have dual implementatations based on whether ended is true or false.

It would be pretty damn ugly, so I'd seriously reconsider my options at this point. There are at least two directions you can take:

  1. Make a Fake implementation of HttpResponseBase instead of using Moq. It sounds like you are expecting such specific behavior of the implementation that a Test Double with embedded logic sounds like a better option. Put shortly, a Fake is a Test Double that can contain semi-complex logic that mimics the intended production implementation. You can read more about Fakes and other Test Doubles in the excellent xUnit Test Patterns book.
  2. Reconsider your initial assumptions. It sounds to me like you are tying your client very closely to a particular behavior of HttpResponseBase, so you may be violating the Liskov Substitution Principle. However, I may be mistaken, as a method called 'End' carries certain connotations beyond the purely semantic, but still, I'd personally consider if a better design was possible.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文