所以我发布了一个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));
它会正常运行。我无法弄清楚如何绕过空引用。
答案 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
。
并且您也没有使用有效参数调用测试中的方法。您需要创建一个具体的实例,模型将null
和null
错误输出。
model.SelectedReport