简体   繁体   中英

How to Test controller method which returns Task<IHttpActionResult> with anonymous type

I have a Web API controller method like given below SessionId is of type 'string'

[HttpPost]
[Route("init")]
[ApiMeter("search_init")]
public async Task<IHttpActionResult> InitiateAsync(SearchInitRequest query,
    CancellationToken cancellationToken)
{
    Validations.EnsureValid(query, new SearchRequestValidator());
    string sessionId = await Service.InitiateSearchAsync(query, cancellationToken);
    return Ok(new { sessionId });
}

And I have test case like below

[Fact]
public void GetSearchInit_Success_Valid()
{
    var mockCarService = new Mock<ICarService>();

    using (new AmbientContextScope(GetCarCallContext()))
    {
        var request = Data.DataProvider.TestDataProvider.GetJsonResult<CarSearchInitRequest>(
       SearchInitScenarioRequests.CarSearchInitSuccess);
        var response = Data.DataProvider.TestDataProvider.GetResponse<CarSearchInitResponse>(
       SearchInitScenarioResponse.CarSearchInitSuccess);

        mockCarService.Setup(f => f.InitiateSearchAsync(request, CancellationToken.None))
            .Returns(Task.FromResult(response.SessionId));

        SearchController controller = new SearchController(mockCarService.Object);
        var result = controller.InitiateAsync(request, CancellationToken.None).Result;
        var status = result as OkNegotiatedContentResult<string>;
        Assert.NotNull(status.Content);

    }
}

in this test case I am getting status as null . though while debugging I can see there is SessionId property inside status.Content but as this is of anonymous type I am not able to read that value.

I have also tried with

var status = result as OkNegotiatedContentResult<object>;

still no luck

Here is a minimal complete example of how you can work around testing the action. This however is more of an integration test as it is going through the framework functionality in order to access the content of the result.

[TestClass]
public class UnitTest6 {
    [TestMethod]
    public async Task Action_Returns_AnonymousTypeResult() {
        //Arrange
        var controller = new SearchController() {
            Configuration = new HttpConfiguration(),
            Request = new HttpRequestMessage()
        };
        var expected = "hello world";

        //Act
        var result = await controller.InitiateAsync();
        var response = await result.ExecuteAsync(CancellationToken.None);
        var status = await response.Content.ReadAsAsync<dynamic>();

        //Assert
        Assert.IsNotNull(status.sessionId);
        Assert.AreEqual(expected, status.sessionId);
    }

    [Authorize]
    public class SearchController : ApiController {
        [HttpPost]
        public async Task<IHttpActionResult> InitiateAsync() {
            string sessionId = await Task.FromResult("hello world");
            return Ok(new { sessionId });
        }
    }
}

By executing the result to get the response message, the content of the response is now accessible. Allowing the content to be parsed as dynamic so that members can be accessed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM