How to write unit test case for BadRequest?

15,308

Each unit test shall test one requirement or concern. Your method implements two requirements:

1) If request is null, return BadRequestErrorMessageResult object with predefined error message. 2) If request's MyID property is empty GUID, return BadRequestErrorMessageResult object with another predefined error message.

This means we should have two unit tests:

[Test]
public async Task CreateDemo_returns_BadRequestErrorMessageResult_when_request_is_null()
{
   // Arrange
   var controller = new HomeController();

   // Act
   var response = await controller.CreateDemo(null);

   // Assert
   Assert.IsInstanceOf<BadRequestErrorMessageResult>(response);
   Assert.AreEqual("request can not be null", response.Message);
}

[Test]
public async Task CreateDemo_returns_BadRequestErrorMessageResult_when_request_ID_is_empty_GUID()
{
   // Arrange
   var controller = new HomeController();
   var request = new MyRequest(Guid.Empty);

   // Act
   var response = await controller.CreateDemo(request);

   // Assert
   Assert.IsInstanceOf<BadRequestErrorMessageResult>(response);
   Assert.AreEqual("MyID must be provided", response.Message);
}

You can go even further and split each of these tests into two where one would test that return object is of the expected type and another that validates that returned object state is as expected (e.g. Message string is as expected). This way you would have a single assert per test.

Side notes:

You tagged this question with nunit tag so I provided the code which uses that framework. In your example though, you use [TestMethod] attribute which comes from Microsoft unit testing framework. If you want to use that framework you'd have to make some changes e.g. replace Assert.IsInstanceOf with Assert.IsInstanceOfType.

I assumed that GUID is passed to MyRequest via its constructor which assigns it to MyID.

I am not coming from web world but I found that BadRequest method has an overload which returns BadRequestErrorMessageResult if string is passed as its argument.

Share:
15,308
Neo
Author by

Neo

Hi! I'm a software engineer. Having experience to work on C#,Asp.Net,AJAX,SQL 2005/08/2012,EF4,SQL to LINQ and also worked on Cloud Computing (Microsoft Windows Azure and AWS Amazon).

Updated on July 20, 2022

Comments

  • Neo
    Neo almost 2 years

    I want to write Unit test cases for following code

    HomeController.cs

    [HttpPost]
            [ActionName("CreateDemo")]
            public async Task<IHttpActionResult> CreateDemo([FromBody] MyRequest request)
            {
                if (request == null)
                {                    
                    return BadRequest("request can not be null");
                }
                if (request.MyID == Guid.Empty)
                {
                    return BadRequest("MyID must be provided");
                }
            }
    

    I tried like following which is not correct way i guess so

     [TestMethod]
            public async Task NullCheck()
            {
                try
                {
                    var controller = new HomeController();
                    var resposne = await controller.CreateDemo(null);
                    Assert.AreEqual(); // not sure what to put here
                }
                catch (HttpResponseException ex) //catch is not hit
                {
                    Assert.IsTrue(
                         ex.Message.Contains("request can not be null"));
                }
    
            }
    
  • Neo
    Neo over 7 years
    thanks , how to use IsInstanceOfType to compare message?
  • Bojan Komazec
    Bojan Komazec over 7 years
    For string assertions, use Assert.AreEqual or, as Nunit3 advises, use constraint model with Equal constraint: Assert.That(response.Message, Is.EqualTo("MyID must be provided"));
  • superninja
    superninja about 6 years
    I would assume it would work the same for XUnit? But It seems to me that the Assertdoesn't have IsInstanceOf in the XUnit framework...