最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - How to test(make sure it comes under Sonar coverage) Catch blocks? - Stack Overflow

programmeradmin5浏览0评论

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"));
}
发布评论

评论列表(0)

  1. 暂无评论