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?
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.
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.
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.
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.
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.
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%.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With