I am trying to test my API by calling an endpoint which should return an error message (json response). When testing this in Postman, the API indeed returns correct JSON and I am able to see that the status code is not 200. However, when trying to test this while using xunit and HttpClient, I am getting the following error message:
System.Net.Http.HttpRequestException : Error while copying content to a stream.
I am trying to figure out why this is happening. In my API I am checking credentials and if they are not correct, I will throw an Exception. This exception will get caught by a global exception handler, which will set the correct status code and create a json response.
Exception handler:
public class ExceptionHandler : IExceptionFilter
{
public void OnException(ExceptionContext context)
{
int status = (int)HttpStatusCode.InternalServerError;
String message = context.Exception.Message;
var exception = context.Exception;
if (exception is ArgumentNullException)
{
message = ((ArgumentNullException)exception).ParamName + " is required";
status = (int)HttpStatusCode.BadRequest;
}
if (exception is NotFoundException)
{
message = exception.Message;
status = (int)HttpStatusCode.NotFound;
}
if (exception is AuthenticationException)
{
message = exception.Message;
status = (int)HttpStatusCode.Unauthorized;
}
if (exception is DuplicateEntryException)
{
message = exception.Message;
status = 422; // Unprocessable entity, not supported in HttpStatusCode class
}
HttpResponse response = context.HttpContext.Response;
response.StatusCode = status;
response.ContentType = "application/json";
response.WriteAsync(JsonConvert.SerializeObject(new ErrorMessage(message, (int)status)));
}
}
class ErrorMessage
{
public string Message { get; set; }
public int Code { get; set; }
public ErrorMessage(string message, int code)
{
Message = message;
Code = code;
}
}
Integration test:
[Fact]
public async Task ItReturnsAnErrorWhenCredentialsAreIncorrect()
{
var request = new UserAuthenticationRequest();
request.Username = "JohnDoe";
request.Password = "TestPasswordIncorrect";
var stringPayload = JsonConvert.SerializeObject(request);
var httpContent = new StringContent(stringPayload, Encoding.UTF8, "application/json");
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = await _client.PostAsync("api/authentication/GetUserAppToken", httpContent);
Assert.Equal(401, (int)response.StatusCode);
}
Anyone having any idea why it is throwing the HttpRequestException?
Update:
Client setup:
public AuthenticationControllerTest()
{
_testServer = new TestServer(new WebHostBuilder().UseStartup<TestStartup>());
_client = _testServer.CreateClient();
}
I did a test by setting up a new client per test method. Unfortunately that also didn't solve the problem
Update 2:
I think it has to do something with either the HttpClient setup or the request message I am sending. Instead of making use of the exception handler, I decided to return a BadRequest() from the controller right away.
public BadRequestResult Post([FromBody]UserAuthenticationRequest userAuthenticationRequest)
{
return BadRequest();
}
When doing that, I am getting a HttpRequestException again, instead of getting a HttpResponse with status code 400.