3

My code coverage has listed my custom exception as 0 test coverage. I am using MsTest,Moq and Fluentassertions. Is there an appropriate unit test for a custom exception?

Here is my Exception class

  public class ConfigurationNotFoundException : Exception
    {
        public ConfigurationNotFoundException()
        {
        }

        public ConfigurationNotFoundException(string message) : base(message)
        {
        }

        public ConfigurationNotFoundException(string message, Exception innerException) : base(message, innerException)
        {
        }

        protected ConfigurationNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context)
        {
        }
    }
Luke Girvin
  • 13,221
  • 9
  • 64
  • 84
MicroMan
  • 1,988
  • 4
  • 32
  • 58

3 Answers3

6

You could write a test which calls each constructor, to satisfy your code coverage tool. But you should determine what code needs testing yourself. If you want to have 100% coverage, go ahead and write a crummy unit test, but you are better off looking at why you write tests. Does adding a trivial unit test increase the quality of your code?

Jonny Cundall
  • 2,552
  • 1
  • 21
  • 33
  • 2
    +1 Agreed. The essential purpose of a unit test is to verify method behavior, and the provided class doesn't really *have* any behavior in its methods. Other than satisfying the code coverage tool, I don't think unit tests would have much use here. – Matt G. Nov 11 '14 at 20:51
  • 5
    Here is value: insuring that someone else doesn't add behavior that causes problems or surprises here. – sfuqua Nov 11 '14 at 20:52
3

Certainly you could write unit tests that call three public constructors. Essentially, your test would be verifying that the constructors do not themselves throw exceptions, and you can verify that the message and innerException are properly stored.

But, this also implies that you are not exercising the code that uses this exception. If you have a MethodA, which can throw this custom exception, then you need to make sure that one of your tests actually causes MethodA to throw the exception.

sfuqua
  • 5,797
  • 1
  • 32
  • 33
  • One of my tests are throwing the exception which i am looking for but that's only 1 constructor. I don't use the other constructor's but they are needed when inheriting from : Exception – MicroMan Nov 11 '14 at 20:53
  • You only need to inherit those constructors if you actually use them somewhere – Jonny Cundall Nov 11 '14 at 20:56
  • Unfortunately you will get static analysis warnings if you don't implement the extra constructors, and thus I usually implement them. I prefer behavior-less constructors to ignored compiler warnings, but that is definitely debatable. – sfuqua Nov 11 '14 at 21:20
3

If it's showing as 0% coverage, it's because it is unused/untested.

Taking your original custom exception class, and this beautiful class which uses it :

public class SomeClass
{
    public void SomeMethod()
    {
        throw new ConfigurationNotFoundException("Hey!");
    }
}

If I have the following Unit Test (with Fluent Assertions) :

[TestClass]
public class SomeClassTest
{
    [TestMethod]
    public void SomeMethodShouldThrow()
    {
        Action invocation = () => new SomeClass().SomeMethod();

        invocation.ShouldThrow<ConfigurationNotFoundException>().WithMessage("Hey!");
    }
}

The coverage shows correctly the used constructor as covered :

Coverage result


So if it's not covered, it is either untested or unused.

To verify if it is unused, you can do a right-click on the method name and select 'Find Usages'. If you have the 'No usages' message, you can safely delete it.

If it is used but untested; test it (the behavior, not the exception class itself).


With our previous example, you'd only need the following :

public class ConfigurationNotFoundException : Exception
{
    public ConfigurationNotFoundException(string message)
        : base(message)
    {
    }
}

The other constructors are not needed to inherit from Exception, and would only clutter the class since they serve no purpose.

Pierre-Luc Pineault
  • 8,993
  • 6
  • 40
  • 55
  • 2
    Your suggestion to delete some of the constructors may not be recommended and FxCop Analyzers can end up with a warning. See https://learn.microsoft.com/cs-cz/visualstudio/code-quality/ca1032-implement-standard-exception-constructors?view=vs-2019 – Martin Žid Aug 20 '19 at 05:50
  • @MartinŽid I understand your point, but personally I'd disable that particular warning. Their explanation of the warning boils pretty much to "Well you might need that in the future, so add it!", which is, IMO, not a great argument. Moreover, if OP's code had been developed in TDD, those constructors would never have appeared in the first place, because there's no use for them. The less code you have (especially dead code as in the OP's example), the easier the codebase is to maintain. – Pierre-Luc Pineault Aug 21 '19 at 11:38
  • 1
    The recommendation to include those constructors come from the fact that the runtime might serialize the exception instance, and when doing so, will need the seemingly useless constructors. I'd say its best to create test methods to use those constructors and decorate them with a comment so its obvious to the reader why those ctors are used – Norbert Hüthmayr Jun 22 '21 at 20:25