您将需要模拟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))
)
);
}
}
现在的测试更加清晰,我们马上就可以看到初始化阶段,该方法的测试和断言实际调用。
备注:所有这一切都被说成我不太明白控制器操作的重点,它只需要一个字节数组作为参数,然后将其传回客户端。我的意思是,为了调用它,客户端需要已经有文件,那么有什么意义?但我想这只是为了说明的目的。在实际的方法中,字节数组不是作为参数传递的,而是在你的控制器动作中从一些外部依赖关系中获取的。在这种情况下,你也可以嘲笑这种依赖(当然,假设你已经正确地构建了你的图层,并且它们耦合得非常弱)。
首先你需要决定你想测试什么? – KingCronus
In Assert it should check,expected file = actual file –
因此,您的第一次测试应该可能是结果实际上是一个文件?然后你可以扩展它,并确保标题是正确的。 – KingCronus