Suitability Considerations When Creating Controllers
I am writing controllers in Web API 2 against which odata requests will run:
[Route("", Name = "GetAccount")]
[HttpGet]
public async Task<IHttpActionResult> GetAccount()
{
var query = Request.RequestUri.PathAndQuery.Split('/')[2]; //this query variable will be something "filter=name eq 'alex'"
var response = _accountService.Get(query);
if (!response.Result.IsSuccessStatusCode)
{
return NotFound();
}
var readAsAsync = response.Result.Content.ReadAsAsync<object>();
if (readAsAsync == null)
{
return NotFound();
}
var result = await readAsAsync;
return Ok(result);
}
How do I insert Request
, in particular, how is it related to var query = Request.RequestUri.PathAndQuery.Split('/')[2];
:?
Here is a very simple test I wrote for this controller:
[TestMethod]
public void GetAccount_Returns_IHttpActionResultTask()
{
var accountsService = new Mock<IAccountService>();
var sut = new AccountsController(accountsService.Object);
Assert.IsInstanceOfType(sut.GetAccount(), typeof(Task<IHttpActionResult>));
}
For testing with different values ββfor Request.RequestUri
.... how can I rewrite my controller to be more testable?
source to share
Set the property Request
to ApiCntroller
.
[TestMethod]
public async Task GetAccount_Returns_IHttpActionResult() {
//Arrange
var accountsService = new Mock<IAccountService>();
var sut = new AccountsController(accountsService.Object);
sut.Request = new HttpRequestMessage {
RequestUri = new Uri("http://localhost/api/accounts?filter=name")
};
//Act
var result = await sut.GetAccount();
//Assert
Assert.IsInstanceOfType(result, typeof(IHttpActionResult));
}
There are also or some potential locking issues with the method under test. Mixing async / await with blocking calls .Result
can cause deadlocks.
Refactoring:
[Route("", Name = "GetAccount")]
[HttpGet]
public async Task<IHttpActionResult> GetAccount() {
var query = Request.RequestUri.PathAndQuery.Split('/')[2]; //this query variable will be something "filter=name eq 'alex'"
var response = await _accountService.Get(query);
if (!response.IsSuccessStatusCode) {
return NotFound();
}
var readAsAsync = response.Content.ReadAsAsync<object>();
if (readAsAsync == null) {
return NotFound();
}
var result = await readAsAsync;
return Ok(result);
}
source to share