I have a web API controller method I want to unit test. It takes in a HttpRequestMessage
but I can't work out how to set the content that I want to pass in. Is it possible to create/mock the HttpRequestMessage
so that I can give it a string
that I want to be the result of await request.Content.ReadAsStringAsync()
?
This is my controller method:
[HttpPost]
public async Task<HttpResponseMessage> Post(HttpRequestMessage request)
{
var data = await request.Content.ReadAsStringAsync();
//do something with data
}
I can easily create the HttpRequestMessage
with its parameterless constructor, but I can't work out how to set the content to a meaningful value. I would like my test to work along these lines:
[TestMethod]
public async Task PostMethodWorks()
{
var controller = new MyController();
var data = "this will be JSON";
var httpRequestMessage = new HttpRequestMessage();
//set the content somehow so that httpRequestMessage.Content.ReadAsStringAsync returns data
var response = await controller.Post(httpRequestMessage);
//assert something about the response here
}
Is it possible to set the value of the content to some JSON, or will I need to change the method so it takes in a different parameter?
(For more context, the reason I want to have the method taking in a HttpRequestMessage
is because I'm working on a legacy codebase with that has loads of controller methods which take in a HttpRequestMessage
.)
HttpRequestMessage(HttpMethod, String) Initializes a new instance of the HttpRequestMessage class with an HTTP method and a request Uri. HttpRequestMessage(HttpMethod, Uri) Initializes a new instance of the HttpRequestMessage class with an HTTP method and a request Uri.
Is it possible to set the value of the content to some JSON
Yes
You can use any one of the many HttpContent
derived classes. Since in this case you want to send JSON content, you would want to use StringContent class
For example
[TestMethod]
public async Task PostMethodWorks() {
//Arrange
var controller = new MyController();
var data = "this will be JSON";
var httpRequestMessage = new HttpRequestMessage();
//set the content somehow so that httpRequestMessage.Content.ReadAsStringAsync returns data
httpRequestMessage.Content = new StringContent(data, Encoding.UTF8, "application/json");
//Act
var response = await controller.Post(httpRequestMessage);
//Assert
//assert something about the response here
}
This however feels like an XY problem as ideally Web API actions don't take HttpRequestMessage
as a argument.
or will I need to change the method so it takes in a different parameter?
Model binders exist that can be used to have strongly typed action parameters that will parse the incoming data and populate the models before passing then to the actions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With