代码之家  ›  专栏  ›  技术社区  ›  Richard Collette

如何使用actionResult进行单元测试?

  •  4
  • Richard Collette  · 技术社区  · 8 年前

    我有一个Xunit测试,比如:

    [fact]
    public async void getlocationsountasync_when called_returnslocationscount())
    {
    _ locationsservice.setup(s=>s.getlocationsountasync(“123”)).returnsasync(10);
    var controller=new locationsController(_locationsService.object,空)
    {
    controllerContext=httpContext=setuphttpContext().object
    };
    var actionresult=await controller.getLocationScountasync();
    actionResult.value.should().be(10);
    verifyall();
    }
    < /代码> 
    
    

    来源是

    摘要 ///获取用户的当前位置数。 ///</summary> ///<退货>A<请参阅cref=“int”></see></returns> ///<response code=“200”>当前位置数。</response> [httpget] [路线(“计数”)] 公共异步任务<actionResult<int>>GetLocationScountask()。 { 返回OK(等待locations.getLocationScountasync(user.appropertyOfteUser()); } < /代码>

    结果的值为空,导致我的测试失败,但如果您查看actionresult.result.value<(an internal property)it contains the expected resolved value.

    请参见以下调试器的屏幕捕获。

    如何获取要在单元测试中填充的actionResult.Value?

    来源是

    /// <summary>
    /// Get the current number of locations for a user.
    /// </summary>
    /// <returns>A <see cref="int"></see>.</returns>
    /// <response code="200">The current number of locations.</response>
    [HttpGet]
    [Route("count")]
    public async Task<ActionResult<int>> GetLocationsCountAsync()
    {
        return Ok(await _locations.GetLocationsCountAsync(User.APropertyOfTheUser()));
    }
    

    结果的值为空,导致我的测试失败,但如果您查看 ActionResult.Result.Value (内部属性)它包含预期的已解析值。

    请参见以下调试器的屏幕捕获。 enter image description here

    如何获取要在单元测试中填充的actionResult.Value?

    1 回复  |  直到 7 年前
        1
  •  3
  •   Nkosi    8 年前

    在运行时,由于隐式转换,被测试的原始代码仍然可以工作。

    但根据提供的调试器图像,测试似乎在断言结果的错误属性。

    因此,当更改测试中的方法允许测试通过时,无论以哪种方式运行,它都会起作用。

    ActioResult<TValue> 根据使用它的操作返回的内容设置了两个属性。

    /// <summary>
    /// Gets the <see cref="ActionResult"/>.
    /// </summary>
    public ActionResult Result { get; }
    
    /// <summary>
    /// Gets the value.
    /// </summary>
    public TValue Value { get; }
    

    Source

    所以当控制器操作返回时, Ok() 它将设置 ActionResult<int>.Result 通过隐式转换的操作结果的属性。

    public static implicit operator ActionResult<TValue>(ActionResult result)
    {
        return new ActionResult<TValue>(result);
    }
    

    但是测试表明 Value 属性(请参阅op中的image),在本例中未设置该属性。

    不需要修改测试中的代码来满足测试,它就可以访问 Result 属性并对该值进行断言

    [Fact]
    public async Task GetLocationsCountAsync_WhenCalled_ReturnsLocationsCount() {
        //Arrange
        _locationsService
            .Setup(_ => _.GetLocationsCountAsync(It.IsAny<string>()))
            .ReturnsAsync(10);
        var controller = new LocationsController(_locationsService.Object, null) {
            ControllerContext = { HttpContext = SetupHttpContext().Object }
        };
    
        //Act
        var actionResult = await controller.GetLocationsCountAsync();
    
        //Assert
        var result = actionResult.Result as OkObjectResult;
        result.Should().NotBeNull();
        result.Value.Should().Be(10);
    
        VerifyAll();
    }