Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I obtain 100% coverage when an exception is thrown in a unit test?

In C# you can catch an exception in the default test suite like this:

[TestMethod]
[ExpectedException(typeof (ArgumentNullException))]
public void TestNullComposite()
{
    IApi api = new Api();
    api.GetDataUsingDataContract(null); // this method throws ArgumentNullException
}

But when you analyze the code coverage, it says that you only get 66.67% coverage because the last curly brace was not covered.

How would I go about achieving 100% coverage on this unit test?

like image 958
stephen Avatar asked Jun 06 '14 21:06

stephen


People also ask

How do you get 100 percent test coverage?

100% test coverage simply means you've written a sufficient amount of tests to cover every line of code in your application. That's it, nothing more, nothing less. If you've structured your tests correctly, this would theoretically mean you can predict what some input would do to get some output.

Can we achieve 100% code coverage?

No. 100% code coverage sounds like a good idea on paper, but it's difficult to achieve and can be very expensive. Developers spend too much time on unit tests that don't provide any value, and 100% code coverage can cause more issues in the code than it prevents.

How do you find the percent unit test coverage?

To calculate the code coverage percentage, simply use the following formula: Code Coverage Percentage = (Number of lines of code executed by a testing algorithm/Total number of lines of code in a system component) * 100.

What happens if a test method throws an exception?

If you write a test method that throws an exception by itself or by the method being tested, the JUnit runner will declare that this test fails.


3 Answers

Usually when people are measuring code coverage, they are looking at the code covered by the tests and not the tests themselves.

As this case shows, it doesn't really make sense to require 100% coverage on test units.

The test is supposed to throw. That is what you are testing.

If you really want the entire method to be executed I guess you could test whether the exception was thrown manually. Something like this (haven't tested it, but I don't see why it shouldn't work):

[TestMethod]
public void TestNullComposite()
{
    IApi api = new Api();
    bool didThrow = false;
    try
    {
        api.GetDataUsingDataContract(null); // this method throws ArgumentNullException
    }
    catch(ArgumentNullException) 
    {
        didThrow = true;
    }
    Assert.IsTrue(didThrow);
}

But it seems like extra work for no good reason. I would suggest you re-evaluate your testing practices.

like image 165
MAV Avatar answered Oct 08 '22 22:10

MAV


Within NUnit you have a method Assert.Throws<Exception>(), which checks if the desired exception was thrown. It also returns that exception as return value, so that you could have further assertations if you like:

[Test]
public void Api_GetDataUsingDataContractWithNullParameter_ThrowsArgumentNullException()
{
    var api = new Api();
    var exception = Assert.Throws<ArgumentNullException>(() => api.GetDataUsingDataContract(null));
    Assert.That(exception.Message, Is.Not.Null.Or.Empty);
    Assert.That(exception.Message, Is.StringContaining("source"));
}

Due to the fact, that the method does not throw by itself, your coverage would be 100%.

like image 37
Oliver Avatar answered Oct 09 '22 00:10

Oliver


What MAV is saying is true. Additionally, there is a way to exclude the test class from being analyzed from Code Coverage.

Just adorn your [TestClass] with the Attribute [ExcludeFromCodeCoverage]!

This way it is at least theoretically possible to reach 100% CC.

like image 34
KarmaEDV Avatar answered Oct 08 '22 22:10

KarmaEDV