简体   繁体   中英

How to get the return message from Web Api Problem?

I have this method in my Web Api.

    [HttpPost("add", Name = "AddCampaign")]
    [ProducesResponseType(StatusCodes.Status201Created)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult<CampaignDTOResponse>> AddCampaign([FromBody] CampaignDTORequest newCampaign)
    {
        try
        {
            var campaign = _mapper.Map<Campaign>(newCampaign);
            campaign = await _campaignService.AddCampaignAsync(campaign);
            var campaignDtoResponse = _mapper.Map<CampaignDTOResponse>(campaign);
            return CreatedAtAction(nameof(GetCampaignById), new { id = campaignDtoResponse.Id }, campaignDtoResponse);
        }
        catch (Exception ex)
        {
            _logger.LogError(0, ex, ex.Message);
            return Problem(ex.Message);
        }
    }

and here is my test in Xunit.

    [Fact]
    public async Task AddCampaign_ReturnBadRequestWhenStartDateIsGreaterThanEndDate()
    {
        var client = _factory.CreateClient();
        string title = string.Format("Test Add Campaign {0}", Guid.NewGuid());
        var campaignAddDto = new CampaignDTORequest
        {
            Title = title, StartDate = new DateTime(2021, 6, 7), EndDate = new DateTime(2021, 6, 6)
        };
        var encodedContent = new StringContent(JsonConvert.SerializeObject(campaignAddDto), Encoding.UTF8, "application/json");

        var response = await client.PostAsync("/api/Campaign/add", encodedContent);

        Assert.False(response.IsSuccessStatusCode);
        Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
    }

When the test pass in invalid date range, I got the validation error message in the Web Api.

在此处输入图片说明

How do I get this validation error message in Xunit so that I can assert it?

Problem is inside ControllerBase class.

控制器库

As per the documentation on MSDN about Problem it returns an instance of ObjectResult .

The ObjectResult is a result, it may contain further data in the form of JSON. By default it contains the data from class ProblemDetails . Also the default status code will be 500.

So in your code following assertions sould pass

Assert.False(response.IsSuccessStatusCode);
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);

To get the error message from the response.. you need to convert the response body to a class object which has the same structure as ProblemDetails class.

public class ApiProblem
{
    public string Type { get; set; }
    public string Title { get; set; }
    public int Status { get; set; }
    public string Detail { get; set; }
    public string TraceId { get; set; }
}

Then you need to deserialize the response body to an object of this class.

var responseContent = await response.Content.ReadAsStringAsync();

var apiProblem = JsonConvert.DeserializeObject<ApiProblem>(responseContent);

And then use Detail property of the object to assert the error message.

Assert.Equal("The campaign start date can not be greater than end date", apiProblem.Detail);

I hope this will help you solve your issue.

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