How to get content value in Xunit when result returned in IActionResult type
Asked Answered
P

2

41

I have a unit test project using Xunit and the method we are testing returns IActionResult.

I saw some people suggest using "NegotiatedContentResult" to get the content of the IActionResult but that doesn't work in Xunit.

So I wonder how to get the content value of an IActionResult in Xunit?

Test code example is provided below:

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);
}

Does anyone know how to do this in XUnit?

Precancel answered 7/9, 2016 at 20:57 Comment(0)
H
52

Depends on what you expect returned. From previous example you used an action like this.

[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);
    }        
}

That method will either return a OkObjectResult or a NotFoundResult. If the expectation of the method under test is for it to return Ok() then you need to cast the result in the test to what you expect and then do your assertions on that

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);
}
Hackle answered 7/9, 2016 at 23:14 Comment(5)
what about if returning dynamic object in ok, for example: Ok(new {token="", expiration=DateTime.Now.AddHours(1)};Nordin
Saved my day. Just to add that I got a warning from RSharper stating "Assert.Equal should be Assert.AreEqual"Ineducation
It seems that there's something more to what's returned. I'm returning IActionResult<List<Donkey>> but when I softly cast the result to List<Donkey> I get null because it's got included properties and the object seems to be of the type QueryableIncludeable or something like that. Never seen that class before...Hypochondriasis
@KonradViltersten That is an invalid cast. Check this article in docs learn.microsoft.com/en-us/aspnet/core/web-api/…Hackle
Sorry, I can't see it in the text. Possibly due to my confusion. I noticed that when I have included something and return an array of such objects that have each one its own inclusion, I had to use that class. Would you be able to elaborate what you meant that the case was invalid, please?Hypochondriasis
F
0

The above solution gives a CS0039 in .NET7.0

Possible solution:

// 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);
Froh answered 18/4, 2023 at 6:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.