我正在尝试模拟存储库方法的结果,该方法将返回类对象列表。如果正在检查结果是否包含数据,则API将根据检查结果返回状态代码。能够模拟结果,但是在检查结果包含数据时抛出空引用异常。这是控制器和测试用例的代码。
public IActionResult Get([FromQuery] FilterRequst request)
{
IEnumerable<Student> result = _repository.GetAll(Mapper.Map<StudentFilter>(request));
if (result != null && result.Count() > 0)//here throwing null reference exception
{
List<StudentModel> model = Fill(result.ToList());
var response = new StudentListModel()
{
TotalRecords = model.Count,
Items = model
};
return new ObjectResult("OK")
{
StatusCode = (int?)HttpStatusCode.OK,
Value = response
};
}
return new ObjectResult("No Content")
{
StatusCode = (int?)HttpStatusCode.NoContent,
Value = "No Content"
};
}
测试用例:
public void StudentGetAllTestReturnsStudents()
{
var fakeStudents = new Mock<IEnumerable<Student>>();
_mockRepository.Setup(x => x.GetAll(It.IsAny<Filter>())).Returns(fakeStudent.Object);
_studentController = new StudentsController(_mockRepository.Object);
Mapper.Initialize(cfg =>
{
cfg.CreateMap<FilterModel, Filter>();
});
// Act
var actionResult = _studentController.Get(It.IsAny<FilterModel>());
var result = actionResult as ObjectResult;
var model = result.Value as StudentListModel;
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(StatusCodes.Status200OK, result.StatusCode);
Assert.IsNotNull(model);
}
如何模拟IEnumerable<Student>
和null
不能被检查的Count
?
答案 0 :(得分:1)
代码无法正常工作的原因有两个。
IEnumerable<>
,但没有对其进行设置,以便其方法和属性返回值。您正在调用.Count()
,但未指定调用该方法时模拟对象应执行的操作。IEnumerable<>
来返回假值,也无法直接模拟.Count()
之类的扩展方法。参见this answer。您不需要模拟IEnumerable
。您只需要模拟您的类,并且仅当您想覆盖它们的默认行为时。
答案 1 :(得分:0)
所安排的设置和被测方法的调用未正确完成
public void StudentGetAllTestReturnsStudents() {
//Arrange
var fakeStudents = new List<Student>() { //used actual list instead of mock
new Student() { }
};
_mockRepository
.Setup(_ => _.GetAll(It.IsAny<StudentFilter>()))
.Returns(fakeStudents);
_studentController = new StudentsController(_mockRepository.Object);
Mapper.Initialize(cfg => {
cfg.CreateMap<FilterRequst, StudentFilter>();
});
// Act
var actionResult = _studentController.Get(new FilterRequst());//use actual model
var result = actionResult as ObjectResult;
var model = result.Value as StudentListModel;
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(StatusCodes.Status200OK, result.StatusCode);
Assert.IsNotNull(model);
}
仅仅因为您可以模拟对象并不意味着您总是应该如此。如果您可以使用实际对象而不会造成负面影响,请继续进行。您可以嘲笑要更改其行为的东西,例如依赖项。
Student
和其他模型应该可以安全地使用其实例,只要它们没有不良行为即可。