【问题标题】:Mocked Controller returning NULL模拟控制器返回 NULL
【发布时间】:2020-04-29 11:43:37
【问题描述】:

我正在使用 xUnit,当我调用控制器的方法时,我得到了null。当我调试时,它不会去RemovePrimeNumbers方法而是返回null

出现这种情况有什么原因吗?

测试方法

public void ControllerTest()
{
    PrimeNumberViewModel returnObject = new PrimeNumberViewModel();
    returnObject.Result = new PrimeNumberModel();

    Mock<IPrimeNumberOperations> _mockService = new Mock<IPrimeNumberOperations>();
    var _controller = new PrimeNumberOperationsController(_mockService.Object) ;

    _mockService.Setup(x => x.RemovePrimeNumbers("Test123")).Returns(returnObject);

    var result = _controller.RemovePrimeNumbers("HAHAHA 2");

    Assert.Equal("HAHAHA 2", result);   
}

控制器

[HttpGet()]
public string RemovePrimeNumbers(string plainText)
{
    PrimeNumberViewModel result = _primeNumberService.RemovePrimeNumbers(plainText);
    return result.Result.removedPrimeNumbersText; // *result* is getting NULL 
}

【问题讨论】:

  • 如果控制器是被测对象,则不应模拟。模拟依赖项并将它们注入到实际的控制器中。

标签: c# unit-testing moq asp.net-core-webapi


【解决方案1】:

你还没有返回值,所以你应该像下面这样返回

var fakePrimeNumberViewModel = new PrimeNumberViewModel { new Result { removedPrimeNumbersText =  "HAHAHA 2"} }
_mockService.Setup(x => x.RemovePrimeNumbers("Test123")).Returns(fakePrimeNumberViewModel);

此外,您应该使用新的Controller 而不是Mock

 var _controller = new PrimeNumberOperationsController(_mockService.Object);

并确保为模拟提供的预期参数与执行测试时使用的参数相同。例如,在您的示例中,模拟设置为期望 "Test123",但是当测试正在执行时,它会给出 "HAHAHA 2",这将导致模拟无法按预期运行。

完整代码:

public void ControllerTest()
{
    //Arrange
    string plainText = "Test123";
    string expected = "HAHAHA 2";
    Mock<IPrimeNumberOperations> _mockService = new Mock<IPrimeNumberOperations>();
    var fakePrimeNumberViewModel = new PrimeNumberViewModel { 
        new Result { removedPrimeNumbersText =  expected} 
    };
    _mockService
        .Setup(x => x.RemovePrimeNumbers(plainText))
        .Returns(fakePrimeNumberViewModel);

    var _controller = new PrimeNumberOperationsController(_mockService.Object);

    //Act
    var actual = _controller.RemovePrimeNumbers(plainText);

    //Assert
    Assert.AreEqual(expected, actual, "Error message");
}

【讨论】:

    【解决方案2】:
    1. 我认为您不应该将 SUT 包裹在 Mock 中
    2. 确保您的安装程序返回一个值
    3. 确保Setup返回的值与调用SUT方法时使用的值相同,否则_primeNumberService.RemovePrimeNumbers上的Setup不会触发,会返回null

    【讨论】:

    • 我也试过了,但它仍然返回 null,@Reed
    • 您的 Setup(x => x.RemovePrimeNumbers("Test123")) 是否与您在 SUT 上调用的匹配 _controller.RemovePrimeNumbers("HAHAHA 2"); ?在这两种情况下都应该是 Test123
    猜你喜欢
    • 2023-03-13
    • 2021-12-24
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 2011-07-09
    • 2012-12-05
    • 1970-01-01
    • 2020-01-08
    相关资源
    最近更新 更多