簡體   English   中英

用Moq框架模擬類

[英]Mocking the class with Moq framework

我正在嘗試模擬存儲庫方法的結果,該方法將返回類對象列表。 如果正在檢查結果是否包含數據,則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> ,可以檢查其是否為非nullCount

您的代碼無法正常工作的原因有兩個。

  1. 您正在模擬IEnumerable<>但沒有對其進行設置,以使其方法和屬性返回值。 您正在調用.Count() ,但未指定調用該方法時.Count()對象應執行的操作。
  2. 即使您確實將IEnumerable<>設置為返回假值,也無法直接模擬擴展方法,例如.Count() 看到這個答案

您不需要模擬IEnumerable 您只需要模擬您的類,並且僅當您想覆蓋它們的默認行為時。

所安排的設置和被測方法的調用未正確完成

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模型和其他模型應該可以安全地使用其實例,只要它們沒有不良行為即可。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM