MVC - Moq单元测试FileContentResult(ActionResult) - NullRefernceException

时间:2016-06-02 00:18:31

标签: c# asp.net-mvc unit-testing moq

所以我发布了一个MVC控制器,它调用存储库来获取Telerik报告,然后导出PDF。我在单元测试时遇到了麻烦,并且一直出现错误 -

  

System.NullReferenceException:未将对象引用设置为对象的实例。

控制器

public class ReportController : Controller
{
    private IPDFRepository _pdfRepository;

    //Dependency Injection using Unity.MVC5 NuGet Package
    public ReportController(IPDFRepository pdfRepository)
    {
        _pdfRepository = pdfRepository;
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult PDFExport(PDFViewModel model)
    {
        byte[] report = _pdfRepository.BuildExport(model);
        return File(report, "application/pdf", model.SelectedReport + ".pdf");
    }
}

单元测试

[TestMethod]
public void Report_PDFExport_Returns_ActionResult()
{
    //Arrange
    var mockRepository = new Mock<IPDFRepository>();
    mockRepository.Setup(x => x.BuildExport(It.IsAny<PDFViewModel>()));

    ReportController controller = new ReportController(mockRepository.Object);

    //Act
    ActionResult result = controller.PDFExport(It.IsAny<PDFViewModel>());

    //Assert
    Assert.IsInstanceOfType(result, typeof(ActionResult));
}

现在,我意识到这与我的控制器的这个返回部分有关。

return File(report, "application/pdf", model.SelectedReport + ".pdf");

我可以改变它来返回字符串,再次测试并使其工作。

另外,如果我注释掉单元测试的最后两行,

//Act
//ActionResult result = controller.PDFExport(It.IsAny<PDFViewModel>());

//Assert
//Assert.IsInstanceOfType(result, typeof(ActionResult));

它会正常运行。我无法弄清楚如何绕过空引用。

1 个答案:

答案 0 :(得分:1)

您没有正确设置 System.Data.DataTable dt = new System.Data.DataTable(); dt.Columns.Add("Code"); System.Data.DataRow r = dt.NewRow(); r["Code"] = "30500"; dt.Rows.Add(r); foreach (System.Data.DataRow row in dt.Rows) { row["CODE"] = row["CODE"].ToString().PadLeft(8, '0'); } dt.AcceptChanges(); 的模拟。它需要配置调用IPDFRepository时要返回的内容。否则BuildExport将为report

并且您也没有使用有效参数调用测试中的方法。您需要创建一个具体的实例,模型将nullnull错误输出。

model.SelectedReport