This is my test method in XUnit.
[Fact]
public async Task AddCampaign_ReturnBadRequestWhenDateIsInvalid()
{
var client = _factory.CreateClient();
string title = string.Format("Test Add Campaign {0}", Guid.NewGuid());
var campaignAddDto = new CampaignDTORequest
{
Title = title
};
var encodedContent = new StringContent(JsonConvert.SerializeObject(campaignAddDto), Encoding.UTF8, "application/json");
var response = await client.PostAsync("/api/Campaign/add", encodedContent);
var responseString = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<CampaignDTOResponse>(responseString);
Assert.False(response.IsSuccessStatusCode);
Assert.ThrowsAsync<ArgumentNullException>(()=> client.PostAsync("/api/Campaign/add", encodedContent));
}
The first assert is works. I am stuck with second assert. How do I assert both exception type (ArgumentNullException) and its exception message?
This is the service method
public async Task<Campaign> AddCampaignAsync(Campaign campaign)
{
if (campaign.StartDate.Equals(DateTime.MinValue)) {
throw new ArgumentNullException("Start Date cannot be null or empty.");
}
await _context.Campaigns.AddAsync(campaign);
await _context.SaveChangesAsync();
return campaign;
}
Updated after the clue from Lei Yang.
var exceptionDetails = Assert.ThrowsAsync<ArgumentNullException>(() => client.PostAsync("/api/Campaign/add", encodedContent));
Assert.Equal("Start Date cannot be null or empty.", exceptionDetails.Result.Message);
But still doesn't work.
System.AggregateException : One or more errors occurred. (Assert.Throws() Failure Expected: typeof(System.ArgumentNullException) Actual: (No exception was thrown))
Tried the solution from Dai but still got error.
Assert.Throws() Failure Expected: typeof(System.ArgumentNullException) Actual: (No exception was thrown)
This is my API method.
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);
}
}
Updated: I move the checking from service to api.
if (newCampaign.StartDate.Equals(DateTime.MinValue))
{
return BadRequest("Start Date cannot be null or empty.");
}
and I assert them like below.
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
Assert.Equal("Start Date cannot be null or empty.", responseString);
Assert.ThrowsAsync is still an async Task method, so you need to await that to ensure the task continuation (that does the actual assert) can run correctly:
[Fact]
public async Task AddCampaign_Return_bad_request_when_date_is_invalid()
{
[...]
Assert.False(response.IsSuccessStatusCode);
await Assert.ThrowsAsync<ArgumentNullException>(()=> client.PostAsync("/api/Campaign/add", encodedContent));
}
ArgumentNullException to represent HTTP 400 Bad Request responses.
ArgumentException class and its subclasses (ArgumentNullException, ArgumentOutOfRangeException, etc) should only be used to indicate a failed precondition - not a failed postcondition nor internal error (use InvalidOperationException for that).ApiException<TResponse> for you, which is far more useful.[ProducesResponseType]).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