Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test IActionResult and its content

I'm developing an ASP.NET Core 2 web api with C# and .NET Core 2.0.

I have changed a method to add it the try-catch to allow me return status codes.

public IEnumerable<GS1AIPresentation> Get()
{
    return _context
        .GS1AI
        .Select(g => _mapper.CreatePresentation(g))
        .ToList();
}

Changed to:

public IActionResult Get()
{
    try
    {
        return Ok(_context
            .GS1AI
            .Select(g => _mapper.CreatePresentation(g))
            .ToList());
    }
    catch (Exception)
    {
        return StatusCode(500);
    }
}

But now I have a problem in my Test method because now it returns an IActionResult instead of a IEnumerable<GS1AIPresentation>:

[Test]
public void ShouldReturnGS1Available()
{
    // Arrange
    MockGS1(mockContext, gs1Data);

    GS1AIController controller =
        new GS1AIController(mockContext.Object, mockMapper.Object);

    // Act
    IEnumerable<Models.GS1AIPresentation> presentations = controller.Get();

    // Arrange
    Assert.AreEqual(presentations.Select(g => g.Id).Intersect(gs1Data.Select(d => d.Id)).Count(),
                    presentations.Count());
}

My problem is here: IEnumerable<Models.GS1AIPresentation> presentations = controller.Get();.

Do I need to do refactor an create a new method to test the Select?

This select:

return _context
    .GS1AI
    .Select(g => _mapper.CreatePresentation(g))
    .ToList();

Or maybe I can get the IEnumerable<Models.GS1AIPresentation> in the IActionResult

like image 280
VansFannel Avatar asked Jan 15 '18 13:01

VansFannel


People also ask

Are controller tests unit tests?

Unit tests of controller logic. Unit tests involve testing a part of an app in isolation from its infrastructure and dependencies. When unit testing controller logic, only the contents of a single action are tested, not the behavior of its dependencies or of the framework itself.

Why write unit tests?

Unit testing allows software developers to actually think through the design of the software and what has to be done before they write the code. This can help them to stay focused and can also help them to create much better designs.


1 Answers

The return Ok(...) called in the controller is returning a OkObjectResult, which is derived from IActionResult so you would need to cast to that type and then access the value within.

[Test]
public void ShouldReturnGS1Available() {
    // Arrange
    MockGS1(mockContext, gs1Data);

    var controller = new GS1AIController(mockContext.Object, mockMapper.Object);

    // Act
    IActionResult result = controller.Get();        

    // Assert
    var okObjectResult = result as OkObjectResult;
    Assert.IsNotNull(okObjectResult);
    var presentations = okObjectResult.Value as IEnumerable<Models.GS1AIPresentation>;
    Assert.IsNotNull(presentations);
    Assert.AreEqual(presentations.Select(g => g.Id).Intersect(gs1Data.Select(d => d.Id)).Count(),
                    presentations.Count());
}

Reference Asp.Net Core Action Results Explained

like image 110
Nkosi Avatar answered Oct 03 '22 13:10

Nkosi