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.
public class Response
{
public string Error { get; set; }
public void SetError(string error)
{
Error = error;
}
}
And the interface
of refit:
public interface IClient
{
[Post("/Controller/MyMethod")]
Task MyMethod([Body]Parameters parameters);
}
The working code could be something like this:
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:
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.
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.
var result = ApiCaller(mockClient.Object);
Assert.That(result == "Error thrown by web api");
History
- 8th September, 2021: Initial version