MVC - Moq 单元测试 FileContentResult (ActionResult) - NullRefernceException
MVC - Moq Unit Test FileContentResult (ActionResult) - NullRefernceException
所以我要发布到 MVC 控制器,它调用存储库以获取 Telerik 报告,然后导出 PDF。我在对此进行单元测试时遇到问题并不断收到错误 -
System.NullReferenceException: Object reference not set to an instance of an object.
控制器
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 部分有关。
return File(report, "application/pdf", model.SelectedReport + ".pdf");
我可以将其更改为 return 字符串,再次测试并使其正常工作。
此外,如果我注释掉单元测试的最后两行,
//Act
//ActionResult result = controller.PDFExport(It.IsAny<PDFViewModel>());
//Assert
//Assert.IsInstanceOfType(result, typeof(ActionResult));
它将 运行 没有错误。我不知道如何绕过空引用。
您没有正确设置 IPDFRepository
的模拟。当 BuildExport
被调用时,它需要配置 return 的内容。否则 report
将是 null
.
而且您也没有使用有效参数调用被测方法。您需要创建一个具体的实例,否则模型将是 null
和 model.SelectedReport
,但会出现错误。
[TestMethod]
public void Report_PDFExport_Returns_ActionResult()
{
//Arrange
byte[] fakePDFReport = new byte[0];
var mockRepository = new Mock<IPDFRepository>();
mockRepository
.Setup(x => x.BuildExport(It.IsAny<PDFViewModel>()))
.Returns(fakePDFReport);
var fakeViewModel = new PDFViewModel {
SelectedReport = "FakeReportName"
//Set the needed properties...
};
ReportController controller = new ReportController(mockRepository.Object);
//Act
ActionResult result = controller.PDFExport(fakeViewModel);
//Assert
Assert.IsInstanceOfType(result, typeof(ActionResult));
}
所以我要发布到 MVC 控制器,它调用存储库以获取 Telerik 报告,然后导出 PDF。我在对此进行单元测试时遇到问题并不断收到错误 -
System.NullReferenceException: Object reference not set to an instance of an object.
控制器
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 部分有关。
return File(report, "application/pdf", model.SelectedReport + ".pdf");
我可以将其更改为 return 字符串,再次测试并使其正常工作。
此外,如果我注释掉单元测试的最后两行,
//Act
//ActionResult result = controller.PDFExport(It.IsAny<PDFViewModel>());
//Assert
//Assert.IsInstanceOfType(result, typeof(ActionResult));
它将 运行 没有错误。我不知道如何绕过空引用。
您没有正确设置 IPDFRepository
的模拟。当 BuildExport
被调用时,它需要配置 return 的内容。否则 report
将是 null
.
而且您也没有使用有效参数调用被测方法。您需要创建一个具体的实例,否则模型将是 null
和 model.SelectedReport
,但会出现错误。
[TestMethod]
public void Report_PDFExport_Returns_ActionResult()
{
//Arrange
byte[] fakePDFReport = new byte[0];
var mockRepository = new Mock<IPDFRepository>();
mockRepository
.Setup(x => x.BuildExport(It.IsAny<PDFViewModel>()))
.Returns(fakePDFReport);
var fakeViewModel = new PDFViewModel {
SelectedReport = "FakeReportName"
//Set the needed properties...
};
ReportController controller = new ReportController(mockRepository.Object);
//Act
ActionResult result = controller.PDFExport(fakeViewModel);
//Assert
Assert.IsInstanceOfType(result, typeof(ActionResult));
}