Nin*_*ore 4 c# nunit asp.net-mvc-3
我正在学习单元测试.如何使用nunit和rhino mock对这个方法进行单元测试?
public ActionResult PrintCSV(Byte[] bytes, string fileName)
{
var file = File(bytes, "application/vnd.ms-excel");
var cd = new System.Net.Mime.ContentDisposition()
{
CreationDate = DateTime.Now,
FileName = fileName,
Inline = false
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return file;
}
Run Code Online (Sandbox Code Playgroud)
您将需要模拟HttpContext.这是一个例子(它是MSTest但是我觉得移植到NUnit并不是很痛苦 - 你需要的只是重命名一些属性):
[TestMethod]
public void PrintCSV_Should_Stream_The_Bytes_Argument_For_Download()
{
// arrange
var sut = new HomeController();
var bytes = new byte[] { 1, 2, 3 };
var fileName = "foobar";
var httpContext = MockRepository.GenerateMock<HttpContextBase>();
var response = MockRepository.GenerateMock<HttpResponseBase>();
httpContext.Expect(x => x.Response).Return(response);
var requestContext = new RequestContext(httpContext, new RouteData());
sut.ControllerContext = new ControllerContext(requestContext, sut);
// act
var actual = sut.PrintCSV(bytes, fileName);
// assert
Assert.IsInstanceOfType(actual, typeof(FileContentResult));
var file = (FileContentResult)actual;
Assert.AreEqual(bytes, file.FileContents);
Assert.AreEqual("application/vnd.ms-excel", file.ContentType);
response.AssertWasCalled(
x => x.AppendHeader(
Arg<string>.Is.Equal("Content-Disposition"),
Arg<string>.Matches(cd => cd.Contains("attachment;") && cd.Contains("filename=" + fileName))
)
);
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,这里有一些管道代码来设置测试.我个人使用MvcContrib.TestHelper,因为它简化了很多这个管道代码,使测试更具可读性.看一下这个:
[TestClass]
public class HomeControllerTests : TestControllerBuilder
{
private HomeController sut;
[TestInitialize]
public void TestInitialize()
{
this.sut = new HomeController();
this.InitializeController(this.sut);
}
[TestMethod]
public void PrintCSV_Should_Stream_The_Bytes_Argument_For_Download()
{
// arrange
var bytes = new byte[] { 1, 2, 3 };
var fileName = "foobar";
// act
var actual = sut.PrintCSV(bytes, fileName);
// assert
var file = actual.AssertResultIs<FileContentResult>();
Assert.AreEqual(bytes, file.FileContents);
Assert.AreEqual("application/vnd.ms-excel", file.ContentType);
this.HttpContext.Response.AssertWasCalled(
x => x.AppendHeader(
Arg<string>.Is.Equal("Content-Disposition"),
Arg<string>.Matches(cd => cd.Contains("attachment;") && cd.Contains("filename=" + fileName))
)
);
}
}
Run Code Online (Sandbox Code Playgroud)
现在测试更加清晰,因为我们可以立即看到初始化阶段,被测试方法的实际调用和断言.
备注:所有这些都说我不太明白控制器动作的意义,它将一个字节数组作为参数,只是为了将它流回客户端.我的意思是,为了调用它,客户端需要已经拥有该文件,那么重点是什么?但我想这只是为了说明目的.在您的实际方法中,字节数组不作为参数传递,而是从控制器操作中从某些外部依赖项中检索.在这种情况下,您也可以模拟这种依赖关系(假设您当然已经正确地构建了图层,并且它们的耦合程度非常弱).
| 归档时间: |
|
| 查看次数: |
2541 次 |
| 最近记录: |