我正在学习的单元测试。 如何单元测试使用NUnit和犀牛嘲笑这种方法吗?
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;
}
您将需要模拟的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))
)
);
}
正如你可以看到这里有一点的管道代码设置测试。 我个人使用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))
)
);
}
}
现在测试是更清楚,马上就可以看到初始化阶段,测试和断言该方法的实际调用。
备注:这一切都这样说我不太看的控制器操作,需要一个字节数组作为参数的点只是以流其返回给客户端。 我的意思是为了调用它的客户端需要已经有文件,有什么意义呢? 但我想那只是为了说明目的。 在实际的方法的字节数组作为参数没有通过但是从一些外部依赖控制器动作内部被检索。 在这种情况下,你可以嘲笑这种依赖性以及(假设当然你已经正确的架构层和它们充分地弱耦合)。