Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing ASP.NET Web API 2 Controller which returns custom result

I have a Web API 2 controller which has an action method like this:

public async Task<IHttpActionResult> Foo(int id)
{
    var foo = await _repository.GetFooAsync(id);
    return foo == null ? (IHttpActionResult)NotFound() : new CssResult(foo.Css);
}

Where CssResult is defined as:

public class CssResult : IHttpActionResult
{
    private readonly string _content;

    public CssResult(string content)
    {
        content.ShouldNotBe(null);
        _content = content;
    }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        var response = new HttpResponseMessage(HttpStatusCode.OK)
        {
            Content = new StringContent(_content, Encoding.UTF8, "text/css")
        };

        return Task.FromResult(response);
    }
}

How do i write a unit test for this?

I tried this:

var response = await controller.Foo(id) as CssResult;

But i don't have access to the actual content, e.g i want to verify that the actual content of the response is the CSS i expect.

Any help please?

Is the solution to simply make the _content field public? (that feels dirty)

like image 683
RPM1984 Avatar asked Jun 10 '15 05:06

RPM1984


People also ask

Can you unit test controllers?

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. Set up unit tests of controller actions to focus on the controller's behavior. A controller unit test avoids scenarios such as filters, routing, and model binding.

Can we return Web API controller view?

You don't return a View from an API controller. But you can return API data from an MVC controller. The solution would be to correct the errors, not try to hack the API controller.

How do I create a controller unit test?

First we need to add an employee class in the Models folder. Following is the Employee class implementation. We need to add EmployeeController. Right-click on the controller folder in the solution explorer and select Add → Controller.


1 Answers

Avoid casts, especially in unit tests. This should work:

var response = await controller.Foo(id);
var message = await response.ExecuteAsync(CancellationToken.None);
var content = await message.Content.ReadAsStringAsync();
Assert.AreEqual("expected CSS", content);
like image 104
Andrei Tătar Avatar answered Oct 27 '22 10:10

Andrei Tătar