3

One of the things I struggle with the most when writing unit tests is what do I test and what do I not test.

So given the following code, what tests should I write:

public static class Enforce
{
    public static T ArgumentNotNull<T>(T parameter, string parameterName) where T : class
    {
        if (parameterName.IsNullOrWhiteSpace())
            throw new ArgumentNullException("parameterName");

        if (parameter.IsNull())
            throw new ArgumentNullException(parameterName);

        return parameter;
    }

    public static string ArgumentNotNullOrEmpty(string parameter, string parameterName)
    {
        ArgumentNotNull(parameter, parameterName);

        if (parameter.IsNullOrEmpty())
            throw new ArgumentException(parameterName);

        return parameter;
    }

    public static string ArgumentNotNullOrWhiteSpace(string parameter, string parameterName)
    {
        ArgumentNotNull(parameter, parameterName);

        if (parameter.IsNullOrWhiteSpace())
            throw new ArgumentException(parameterName);

        return parameter;
    }

    public static T NotNull<T>(T instance) where T : class
    {
        instance.IfNullThrow<T, NullReferenceException>(String.Format(EnforceResources.TypeNotNull, typeof(T).FullName));

        return instance;
    }
}

}

Should I write a test for ArgumentNotNull<T> that tests for the exception being thrown and then one that tests for the exception NOT being thrown? I guess my question is, should I write my tests that test for the expected and then the exact opposite?

    [Fact]
    public void ShouldThrowArgumentNullException()
    {
        object arg = null;

        Assert.Throws<ArgumentNullException>(() => { Enforce.ArgumentNotNull(arg, "arg"); });
    }

    [Fact]
    public void ShouldNotThrowArgumentNullException()
    {
        var arg = "Test";

        Assert.DoesNotThrow(() => { Enforce.ArgumentNotNull(arg, "arg"); });
    }
Sam
  • 15,336
  • 25
  • 85
  • 148

2 Answers2

1

You should do your best to test ALL your code. That means all public methods and the scenarios within them to get as much coverage as you can of all its internal logic.

So you should write 3 tests: one for the first exception, one for the second, and one where none are thrown.

Regarding the naming convention for those tests this might be of interest: https://stackoverflow.com/a/1594049/1373170

Community
  • 1
  • 1
Pablo Romeo
  • 11,298
  • 2
  • 30
  • 58
  • How about naming those tests? Do you have any thoughts on what that might look like? – Sam Mar 17 '13 at 07:38
1

Unit testing concept is to make sure your code works exactly as you expect it to work,

therefore if you expect it to throw exception it should be tested for the right exception.

here are some basic concepts and tips about writing unit tests:

http://www.slideshare.net/homespothq/unit-testing-concepts-and-best-practices

Dror Ventura
  • 11
  • 1
  • 4