-1

Can anyone help me to write the second assert for the following unit test? Actually I want to test if CategoryId is greater than 0 and I want to use my response data (CategoryId is auto generated here because of Identity column)

 [Fact]
 public async Task PostValidObjectReturnsOkResult()
 {
     //Arrange
     Mock <ICategoryService> m = new Mock <ICategoryService>();
           
     CategoryDTO myData = new CategoryDTO()
     {
          CategoryName = "Items" 
     };

     m.Setup(repo => repo.CreateCategory(myData));

     CategoryController c = new CategoryController(m.Object);

     //Act
     ActionResult response = await c.Post(myData);//response data
        
     //Assert
     Assert.IsType <OkObjectResult>(response);
}

I tried the followings but it did not work:

Assert.NotEqual(0,(response.Value as CategoryDTO).CategoryId);
Assert.True(((response.Value as CategoryDTO).CategoryId) > 0);
MZG
  • 327
  • 2
  • 12

3 Answers3

1

I finally fixed it like this:

var okResult = Assert.IsType<OkObjectResult>(response);
Assert.NotEqual(0, (okResult.Value as CategoryDTO).CategoryId);

Also I changed this line of code:

m.Setup(repo => repo.CreateCategory(myData));

to the following code because we need to specify Returns() in order to give you some random number for CategoryId

m.Setup(i => i.CreateCategory(It.IsAny<CategoryDTO>())).Returns(() => Task.FromResult(myData));
MZG
  • 327
  • 2
  • 12
0

Assert.IsType will return the casted type. Try:

var okResult = Assert.IsType<OkObjectResult>(response);

Assert.True(okResult.Value.CategoryId > 0);
Jonesopolis
  • 25,034
  • 12
  • 68
  • 112
  • thank you for the answer but I am getting error for CategoryId here it says "object does not have definition for CategoryId" – MZG Oct 04 '20 at 01:57
0

It looks like what you are trying to test is the behavior of assigning values from ICategoryService back to the CategoryDTO object. In this case the mock implementation of ICategoryService will need to provide the same results as the concrete implementation. It looks like you are using Moq, and in order to implement a check you might use a callback to check the following:

var expectedCategoryId = 42;
m.Setup(repo => repo.CreateCategory(myData))
 .Callback(() => myData.CategoryId = expectedCategoryId);

// The rest of the testing code

Assert.Equal(expectedCategoryId, resultValue.CategoryId);

If the object that is passed into the service is the same object that is returned in the controller's OK response, then you may want to adjust the test to verify the expectations of the mock service:

// The rest of the testing code

m.VerifyAll();

Also as @Jonesopolis suggests instead of casting types using the as operator, you should use the return result from Assert.IsType<T>. With a slight adjustment to their code, this should simplify what your test logic should look like:

// The rest of the testing code

var okObjectResult = Assert.IsType<OkObjectResult>(response);
var resultValue = Assert.IsType<CategoryDTO>(okObjectResult);
Assert.True(resultValue.CategoryId > 0, "Result value does not have CategoryId assigned");

Also note that I have included a message alongside the Assert.True check. This allows the testing framework to give better feedback when the test fails.

joncloud
  • 757
  • 5
  • 14