admin管理员组

文章数量:1355574

I am new to NUnit(3.4+) and somehow not able to solve the below simple issue :)

I want to make sure the catch blocks are covered in Sonar coverage and for that want to write a Nunit test case. I have tried couple of things but nothing worked for me and kept getting error/test failure. This is my testable method. (Note for some reason, I can not change the methods just for Nunit test case.)

public async Task<List<ReturnObjects>> GetData(int Id)
{
   try
   {
   }
   catch(Exception)
   {
   }

My test case:

    [Test]
    public async Task CanCallGetData_Test_ThrowsException()
    {
    // Arrange</p>
    var Id = 927810493;</p>
    List<ReturnObjects> objs = null; //I tried making it null, so null reference 
                                     //exception will throw.

    //Some repo class with mock data</p>
    _queryHelperDataMart.Setup(mock => mock.WrapQueryAsync<ReturnObjects> 
    (It.IsAny<string>(), It.IsAny<IConfiguration>(), It.IsAny<Dictionary<string, 
    object>>(), 
    It.IsAny<string>())).ReturnsAsync(objs);

    // Act
    var result = Assert.ThrowsAsync<Exception>(() => _testClass.GetData(Id));

    // Assert
    Assert.That(result, ..check exception etc);
    } 

I keep getting Expected: <System.Exception> But was: null What I am missing here? Also, please let me know how to write a testable code for catch blocks when not possible to generate actual exception from test method?

I am new to NUnit(3.4+) and somehow not able to solve the below simple issue :)

I want to make sure the catch blocks are covered in Sonar coverage and for that want to write a Nunit test case. I have tried couple of things but nothing worked for me and kept getting error/test failure. This is my testable method. (Note for some reason, I can not change the methods just for Nunit test case.)

public async Task<List<ReturnObjects>> GetData(int Id)
{
   try
   {
   }
   catch(Exception)
   {
   }

My test case:

    [Test]
    public async Task CanCallGetData_Test_ThrowsException()
    {
    // Arrange</p>
    var Id = 927810493;</p>
    List<ReturnObjects> objs = null; //I tried making it null, so null reference 
                                     //exception will throw.

    //Some repo class with mock data</p>
    _queryHelperDataMart.Setup(mock => mock.WrapQueryAsync<ReturnObjects> 
    (It.IsAny<string>(), It.IsAny<IConfiguration>(), It.IsAny<Dictionary<string, 
    object>>(), 
    It.IsAny<string>())).ReturnsAsync(objs);

    // Act
    var result = Assert.ThrowsAsync<Exception>(() => _testClass.GetData(Id));

    // Assert
    Assert.That(result, ..check exception etc);
    } 

I keep getting Expected: <System.Exception> But was: null What I am missing here? Also, please let me know how to write a testable code for catch blocks when not possible to generate actual exception from test method?

Share Improve this question asked Mar 31 at 5:10 MB22MB22 316 bronze badges 5
  • Short answer - you can't. Longer answer - we need to see the code in GetData to give better advice. – mjwills Commented Mar 31 at 5:12
  • stackoverflow/a/73238216/34092 – mjwills Commented Mar 31 at 5:14
  • Assert.ThrowsAsync is testing whether an exception escaped the method - not that it was caught in the method. – mjwills Commented Mar 31 at 5:17
  • Just confirming that Moq is in use here, too, right? – Fildor Commented Mar 31 at 8:13
  • @Fildor, yes Moq is used here. – MB22 Commented Mar 31 at 12:30
Add a comment  | 

1 Answer 1

Reset to default 3

As already mentioned, if you catch exception, Assert.ThrowsAsync won't work, as it checks if excpetion was thrown by the method you invoke (so it was not caught).

But it is good approach to cover catch block. However, you must validate that code inside catch was executed.

And in order to throw exception in unit test, you better setup your mock to do so. Something like below:

[Test]
public void Test1()
{
    // Arrange
    var queryHelperDataMart = new Mock<IQueryHelperMart>();
    queryHelperDataMart.Setup(mock => mock.WrapQueryAsync(It.IsAny<string>())).Throws(new Exception());
    var testClass = new SystemUnderTest(queryHelperDataMart.Object);

    // Act
    var result = testClass.GetData("anything");

    // Assert
    Assert.That(result, Is.Null);
}

Sometimes I find myself in such situation, that there is nothing much to assert in catch block, so i tend to write such unit tests, to assure that in case of exception, code under test will handle it:

[Test]
public void Test1()
{
    // Arrange
    var queryHelperDataMart = new Mock<IQueryHelperMart>();
    queryHelperDataMart.Setup(mock => mock.WrapQueryAsync(It.IsAny<string>())).Throws(new Exception());
    var testClass = new SystemUnderTest(queryHelperDataMart.Object);

    // Act & Assert
    Assert.DoesNotThrow(() => testClass.GetData("anything"));
}

本文标签: cHow to test(make sure it comes under Sonar coverage) Catch blocksStack Overflow