如何在Xunit中获取IActionResult类型返回结果的内容值

41

我有一个使用Xunit的单元测试项目,我们正在测试的方法返回 IActionResult

我看到有人建议使用 "NegotiatedContentResult" 来获取 IActionResult 的内容,但在Xunit中无法使用该方法。

所以我想知道如何在Xunit中获取 IActionResult 的内容值?

以下是测试代码示例:

public void GetTest()
{
    var getTest = new ResourcesController(mockDb);

    var result = getTest.Get("1");

    //Here I want to convert the result to my model called Resource and
    //compare the attribute Description like below.
    Resource r = ?? //to get the content value of the IActionResult

    Assert.Equal("test", r.Description);
}

有人知道如何在XUnit中实现这个吗?

2个回答

51

取决于您期望返回的内容。从之前的示例中,您使用了类似以下操作。

[HttpGet("{id}")]
public IActionResult Get(string id) {        
    var r = unitOfWork.Resources.Get(id);

    unitOfWork.Complete();

    Models.Resource result = ConvertResourceFromCoreToApi(r);

    if (result == null) {
        return NotFound();
    } else {
        return Ok(result);
    }        
}

该方法将返回OkObjectResultNotFoundResult。如果被测试的方法期望返回Ok(),则需要在测试中将结果转换为您期望的类型,并在其上执行断言。

public void GetTest_Given_Id_Should_Return_OkObjectResult_With_Resource() {
    //Arrange
    var expected = "test";
    var controller = new ResourcesController(mockDb);

    //Act
    var actionResult = controller.Get("1");

    //Assert
    var okObjectResult = actionResult as OkObjectResult;
    Assert.NotNull(okObjectResult);

    var model = okObjectResult.Value as Models.Resource;
    Assert.NotNull(model);

    var actual = model.Description;
    Assert.Equal(expected, actual);
}

5
如果在Ok中返回动态对象,例如:Ok(new { token="", expiration=DateTime.Now.AddHours(1)}),怎么样? - mesut
救了我的一天。只是想补充一下,我收到了来自 RSharper 的警告,指出“Assert.Equal 应该是 Assert.AreEqual”。 - Ruben D. Lopez
似乎返回的内容还有更多。我正在返回IActionResult<List<Donkey>>,但是当我将结果弱转换为List<Donkey>时,我得到了null,因为它包含了属性,而且对象似乎是类型为QueryableIncludeable或类似的类型。以前从未见过这个类... - Konrad Viltersten
@KonradViltersten 这是一个无效的转换。请查看文档中的此文章 https://learn.microsoft.com/en-us/aspnet/core/web-api/action-return-types?view=aspnetcore-2.2#actionresultt-type - Nkosi
抱歉,我在文本中看不到它。可能是因为我的困惑。我注意到当我包含某些内容并返回一个具有各自独立包含的对象数组时,我必须使用该类。您能否详细说明您所说的情况无效是什么意思? - Konrad Viltersten

0

以上解决方案在.NET7.0中会出现CS0039错误。

可能的解决方案:

// Arrange
var expected = "test";
var controller = new ResourcesController(mockDb);

// Act
var actionResult = controller.Get("1");

// Assert
actionResult.Should().NotBeNull();
actionResult.Result.Should().BeOfType<OkObjectResult>();

var model = (actionResult.Result as OkObjectResult)!.Value as string;
model.Should().NotBeNull();
model.Should().BeEquivalentTo(expected);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接