如何对在操作中具有私有方法的ASP.Net MVC控制器进行单元测试
本文关键字:Net ASP MVC 控制器 单元测试 有方法 操作 | 更新日期: 2023-09-27 18:28:54
在尝试测试ASP.Net MVC控制器/操作时,我很难理解单元测试模式。
使用以下代码,我试图为ShowPerson()
方法编写一个测试:
public class PersonController : Controller
{
private IDataAccessBlock _dab;
public PersonController()
: this(new DataAccessBlock())
{ }
public PersonController(IDataAccessBlock dab)
{
_dab = dab;
}
public ActionResult ShowPerson(PersonRequestViewModel personRequest)
{
var person = GetPersonViewModel(personRequest);
return View("Person", person);
}
private PersonViewModel GetPersonViewModel(PersonRequestViewModel personRequest)
{
var personService = new CommonDomainService.PersonService(_dab);
var dt = personService.GetPersonInfo(personRequest.Id);
var person = new PersonViewModel();
if (dt.Rows.Count == 1)
{
person.FirstName = dt.Rows[0]r["FIRSTNAME"]);
person.LastName = dt.Rows[0]["LASTNAME"];
}
return person;
}
}
我正在使用的测试(使用UnUnit和Moq):
[Test]
public void ShowPerson_Action_Should_Return_Person_View()
{
// Arrange
string expected = "Person";
Mock<PersonRequestViewModel> personRequestViewModelMock = new Mock<PersonRequestViewModel>();
personRequestViewModelMock.SetupProperty(f => f.Id, 123456);
Mock<IDataAccessBlock> mockDab = new Mock<IDataAccessBlock>();
PersonController personController = new PersonController(mockDab.Object);
// Act
ViewResult result = personController.ShowPerson(personRequestViewModelMock.Object) as ViewResult;
// Assert
personRequestViewModelMock.Verify();
result.Should().Not.Be.Null();
if (result != null) Assert.AreEqual(expected, result.ViewName, "Unexpected view name");
}
一切似乎都很顺利,直到遇到线路if (dt.Rows.Count == 1)
。我得到一个"Object reference not set to a instance of a Object"
我认为以下两行的书写方式一定有些怪异:
var personService = new CommonDomainService.PersonService(_dab);
var dt = personService.GetPersonInfo(personRequest.Id);
但我不知道从这里到哪里去。我有很多这样的代码。我是做错了什么,还是有实际的方法来测试这一点?
谢谢你的帮助或指点。
是您的CommonDomainService.PersonService是托管在Web应用程序中的某种Web服务,当您运行测试时,您的Web应用程序将不会运行,服务也将无法访问。理想情况下,您的控制器依赖于您在私有方法中创建的CommonDomainService.PersonService,而应该将其注入控制器(就像您对DataAccess块所做的那样),并在测试方法中对其进行模拟。
写入私有只读IDataAccessBlock _dab;而不是私有IDataAccessBlock _dab;