- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在使用 Moq 创建一个 Mock<HttpResponseBase>
测试 FileResult
我正在为我的 MVC2 应用程序创建。
在WriteFile(HttpResponseBase response)
FileResult
的方法,最后我有以下代码:
// Write the final output with specific encoding.
response.OutputStream.Write(output, 0, output.Length);
response.AppendHeader("Content-Encoding", encoding);
它将使用 utf-8
或 gzip
取决于请求的 Accept-Encoding
的编码标题。
然后在我的测试中,我设置了我的 Mock<HttpResponseBase>
像这样:
var mockResponse = new Mock<HttpResponseBase>();
mockResponse.Setup(r => r.OutputStream).Returns(new MemoryStream());
mockResponse.Setup(r => r.Headers).Returns(new NameValueCollection());
但是当我实际检查标题是否已设置时,Content-Encoding
总是返回空值:
var response = mockResponse.Object;
Assert.AreEqual("utf-8", response.Headers["Content-Encoding"]);
奇怪的是 OutputStream 得到了写入它的数据,我可以断言它正在写入正确的值。
奇怪的是,当我实际调试 FileResult
时在 Web 项目中, header 已正确发送。
有没有人对此有所了解?如有必要,我可以提供更多代码。
最佳答案
您遇到的问题与您试图部分模拟 HttpResponseBase
类这一事实有关。写入输出流是可行的,因为该属性(在本例中为 OutputStream
)被模拟并从 SUT(被测系统)访问。
但是,当您模拟 Headers
属性时,只会模拟该属性,而不是 AppendHeader
,这是您的 SUT 实际执行的操作。 Moq 创建的默认模拟只是将所有方法和属性作为返回默认值 stub ,因此 AppendHeader
实际上不执行任何操作。
对此有两种解决方案,第一种是纯粹的交互测试,这是我的首选方法。不要模拟 Headers
,而是验证 AppendHeader
。
Mock<HttpResponseBase> responseMock = new Mock<HttpResponseBase>();
//the rest of response setup
FileResult sut = new MyFileResult();
sut.WriteFile(responseMock.Object);
responseMock.Verify(response=>response.AppendHeader("Content-Encoding", "utf8"));
第二种方法是利用 Moq 的部分模拟,这将使模拟对象调用实际类的方法,除非它们已被显式设置。
Mock<HttpResponseBase> responseMock = new Mock<HttpResponseBase>(){ CallBase = true };
//the rest of response setup
FileResult sut = new MyFileResult();
sut.WriteFile(responseMock.Object);
Assert.AreEqual("utf-8", responseMock.Object.Headers["Content-Encoding"]);
我更喜欢第一个版本,因为您正在测试与框架的交互。第二个版本更像是一个基于状态的测试,所以理论上你甚至不需要模拟,你可以只使用实际的类。然而,在 HttpResponseBase
的情况下,它几乎是有意义的,因为它的构造函数是 protected ,因此通过创建模拟,您基本上是从它内联派生的,而无需手动编写测试替身。
关于c# - 运行测试时 HttpResponseBase.Headers 为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4066184/
我正在使用 Moq 创建 HttpResponseBase 的模拟对象。我需要能够测试 HttpResponseBase.End() 在我的库中被调用。为此,我在调用前和调用后指定了一些文本。然后我检
我正在使用 Moq 创建一个 Mock测试 FileResult我正在为我的 MVC2 应用程序创建。 在WriteFile(HttpResponseBase response) FileResult
在 Controller 操作中,我使用 WebRequest 手动将表单发送到远程 URL。我成功收到包含要显示的 html 页面的 WebResponse。我想将此响应“粘贴”为操作的响应(类型为
我正在将一些代码从旧的 MVC 5 应用程序移植到 Core 2.0 应用程序。 SerializeData 方法失败,因为 HttpResponseBase 不再出现在 Core 2.0 中,而且我
我正在将大型 .NET Framework 项目转换为 .NET Core 项目,并且遇到以下代码: public class ContentStreamingResult : ActionResul
我是一名优秀的程序员,十分优秀!