我如何模拟HttpResponseBase.End()?

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

问题是,我无法弄清楚如何模拟HttpResponseBase.End()以便它停止处理,就像在ASP.NET中一样。

public static HttpResponseBase CreateHttpResponseBase() { var mock = new Mock(); 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())) .Callback(s => output.Write(s)); return mock.Object; } 

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

一般来说,使用Moq并不是特别容易,因为它没有有序期望的概念(与RhinoMocks不同)。 但是,有一个function请求 。

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

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

然后让所有其他安装程序根据ended是true还是false进行双重实现。

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

  1. 做一个假的HttpResponseBase实现,而不是使用Moq。 听起来您期望实现的这种特定行为,具有嵌入式逻辑的Test Double听起来像是更好的选择。 简而言之,假的是一个测试双,它可以包含模拟预期生产实现的半复杂逻辑。 您可以在优秀的xUnit Test Patterns一书中阅读有关Fakes和其他Test Doubles的更多信息。
  2. 重新考虑你的初步假设。 听起来像是你将你的客户与HttpResponseBase的特定行为紧密联系在一起,所以你可能违反了Liskov Substitution Principle。 然而,我可能会错,因为一种名为“结束”的方法带有超出纯粹语义的某些内涵,但我仍然会考虑是否有更好的设计。