简体   繁体   中英

How to properly get the result of controller in nunit?

I have a ASP.NET Core WebAPI project and I´m having some trouble to test the controllers.

In my controller I have the following action:

[HttpGet]
public async Task<ActionResult<ListUsersDto>> Get()
{
    var users = await _userService.GetAllUsers();
    return Ok(users);
}

So my test is:

[Test]
public async Task Get_ReturnsAllUsers()
{
    var listUsersDto = new ListUsersDto();
    listUsersDto.Users.Add(
           new UserDto()
           {
               Id = DEFAULT_TRUCK_ID,
               Color = "White",
               CreationDate = date,
               EditDate = date,
               ManufactureYear = date.Year,
               ModelYear = date.Year
            }
    );
    _userService.Setup(m => m.GetAll()).ReturnsAsync(listUsersDto);
    var controller = GetController();
    var response = await controller.Get();            
    Assert.IsInstanceOf(typeof(OkObjectResult), response.Result);
}

This test passes normally. But I cant figure how to get the actual values of the return.

Assert.AreEqual(1, response.Value.Users.Count);
//This test fails because the Value is empty.

The Value property of the response is always empty. If I debug the test I can see that the await controller.Get(); returns the correct object. What am I missing here?

Because the action is defined to return ActionResult<ListUsersDto> and you are returning Ok(users) , then what you describe is by design.

Value will be empty because an action result is being returned. ActionResult<T> return one or the other. Not Both.

Because of the Ok(users) you would need to extract the value from the returned action result.

//Act
var response = await controller.Get();            

//Assert
OkObjectResult result = Assert.IsInstanceOf<OkObjectResult>(response.Result);
//assert the value within the object result.
ListUsersDto dto = Assert.IsInstanceOf<ListUsersDto>(result.Value);
Assert.AreEqual(1, dto.Users.Count);

Things would have been different is for example the action was defined differently

[HttpGet]
public async Task<ActionResult<ListUsersDto>> Get() {
    var users = await _userService.GetAllUsers();

    if(users == null || users.Users.Count == 0)
        return NoContent(); //Or some other relevant action result

    return users;
}

And the test tested like you did originally

[Test]
public async Task Get_ReturnsAllUsers() {
    //Arrange
    var listUsersDto = new ListUsersDto();
    listUsersDto.Users.Add(
           new UserDto()
           {
               Id = DEFAULT_TRUCK_ID,
               Color = "White",
               CreationDate = date,
               EditDate = date,
               ManufactureYear = date.Year,
               ModelYear = date.Year
            }
    );
    _userService.Setup(_ => _.GetAllUsers()).ReturnsAsync(listUsersDto);
    var controller = GetController();

    //Act
    var response = await controller.Get();

    //Assert
    Assert.AreEqual(1, response.Value.Users.Count);
}

Then because the action returned the result object directly, then the ActionResult<ListUsersDto>.Value property would be populated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM