Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Mock ApiException on Refit

0.00/5 (No votes)
7 Sep 2021CPOL1 min read 13.6K  
Test Refit status code response 422 (or else) with mock and ApiException
How to use Mock and Refit to test that the application correctly reports the 422 status code and a string error (or anything else).

Introduction

I use Refit to call web API in my code.

I also like use StatusCode 422 when the web API have to report that there is a logic error in the application and not an exception and use test, to verify the code.

So I want to write here about this problem, how, with mock and Refit, we can test that the application reports correctly the 422 status code and a string error (or anything else).

Web API

My web API has a class with a Response and an Error property.

C#
public class Response
{
    public string Error { get; set; }
    public void SetError(string error)
    {
        Error = error;
    }
}

And the interface of refit:

C#
public interface IClient
{
    [Post("/Controller/MyMethod")]
    Task MyMethod([Body]Parameters parameters);
}

The working code could be something like this:

C#
public string ApiCaller(IClient client)
{
    try
    {
        await client.MyMethod
        (
            new Parameters(...);
        );
    }
    catch(ApiException ex) when (ex.StatusCode == HttpStatusCode.UnprocessableEntty)
    {
        return ex.GetContentAsync().Result.Errors
    }
    return string.Empty;
}

With this code, we can retrieve the error when Refit throws an ApiException. If another Exception is throws(500, 404 ...), there will be an exception that we can catch with another catch statement or in a centralized way.

The Test

We use an MockApiException to build the exception used by mock:

C#
public static MockApiException
{
    public static ApiException CreateApiException(HttpStatusCode statusCode, T content)
    {
        var refitSettings = new RefitSettings;
        return ApiException.Create(null, null, 
            new HttpResponseMessage
            {
                StatusCode = statusCode,
                Content = refitSettings.ContentSerializer.ToHttpContent(content)
            }, refitSettings).result;
    }
}

We can Mock the client and use MockApiException to build the exception that mock will throw.

C#
var response = new Response("Error thrown by web api")
var mockClient = new Mock();
mockClient.Setup(x => x.MyMethod(
    It.Is(...)
))
.Thrown(MockApiException.CreateApiException(HttpStatusCode.UnprocessableEntity, response);

Now you can test that when we call ApiCaller and refit throw a 422 Exception, the result is equal to the error.

C#
var result = ApiCaller(mockClient.Object);  
Assert.That(result == "Error thrown by web api");

History

  • 8th September, 2021: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)