简体   繁体   English

如何在C#中对该方法进行单元测试?

[英]How to unit test this method in c#?

i am learning unit testing. 我正在学习单元测试。 How to unit test this method using nunit and rhino mock ? 如何使用nunit和rhino模拟对这种方法进行单元测试?

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;
}

You will need to mock the HttpContext. 您将需要模拟HttpContext。 Here's an example (it's MSTest but I guess it won't be a hell lot of a pain to port to NUnit - all you need is to rename a couple of attributes): 这是一个示例(它是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))
        )
    );
}

As you can see there's a bit of a plumbing code here to setup the test. 如您所见,这里有一些管道代码来设置测试。 Personally I use MvcContrib.TestHelper as it simplifies a lot of this plumbing code and makes the test more readable. 我个人使用MvcContrib.TestHelper,因为它简化了许多此类管道代码,并使测试更具可读性。 Check this out: 看一下这个:

[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))
            )
        );
    }
}

Now the test is much more clear as we can immediately see the initialization phase, the actual invoke of the method under test and the assertion. 现在,测试变得更加清晰,因为我们可以立即看到初始化阶段,被测方法的实际调用和断言。

Remark: All this being said I don't quite see the point of a controller action that takes a byte array as argument just to stream it back to the client. 备注:话虽如此,我还不太明白控制器操作的意义,该操作需要将字节数组作为参数只是将其流回客户端。 I mean in order to invoke it the client needs to already have the file, so what's the point? 我的意思是要调用它,客户端需要已经有文件,所以有什么意义呢? But I guess that was just for illustration purposes. 但我想那只是出于说明目的。 In your actual method the byte array is not passed as argument but is retrieved inside your controller action from some external dependency. 在您的实际方法中,字节数组不作为参数传递,而是从某些外部依赖项在您的控制器动作内部检索的。 In this case you could mock this dependency as well (assuming of course you have properly architected your layers and they are sufficiently weakly coupled). 在这种情况下,您也可以模拟这种依赖关系(当然,假设您已经正确构造了图层,并且它们之间的耦合程度很弱)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM