Question

Working on reorganizing my unit tests, I'm currently looking at different possibilities to achieve this:

CustomerTests

[TestClass]
public class CustomerTests : SuperTestBaseClass {
    public CustomerTests() : base() { }

    [TestMethod]
    public void NameThrowsWhenNull() { 
        Throws<ArgumentNullException>(customer.Name = null);
    }
}

SuperTestBaseClass

public abstract class SuperTestBaseClass {
    protected SuperTestBaseClass() { }

    public void Throws<TException>(Func<T, TResult> propertyOrMethod) {
        // arrange
        Type expected = typeof(TException);
        Exception actual = null;

        // act
        try { propertyOrMethod(); } catch (Exception ex) { actual = ex; }

        // assert
        Assert.IsInstanceOfType(actual, expected);
    }
}

Where the propertyOrMethod would get executed there in the try/catch, without having to write something like:

try { propertyOrMethod.Name = null } catch...

Since the goal is to make this method the most generic possible to promote code reuse.

It is feasible? If yes, then how?

Was it helpful?

Solution 2

I would do:

public TException Throws<TException>(Action act) where TException : Exception 
{
        // act
        try { act(); } catch (TException ex) { return ex; }

        // assert
        Assert.Fail("Expected exception");
        return default(TException);   //never reached
}

Then you can do

Throws<ArgumentNullException>(() => { customer.Name = null; });

Note that NUnit has this method built in (Assert.Throws/Catch) so you don't need this if you're using that.

OTHER TIPS

Use [ExpectedException(typeof(ArgumentNullException)] on your method, and you won't need any custom stuff.

[TestClass]
public class CustomerTests : SuperTestBaseClass {
    public CustomerTests() : base() { }

    [TestMethod]
    [ExpectedException(typeof(ArgumentNullException)]
    public void NameThrowsWhenNull() { 
        customer.Name = null;
    }
}

If you use NUnit then you can do this:

Assert.That(() => { ... }, Throws.InstanceOf<ArgumentException>()));

You can substitute the lambda expression for a delegate instance if you need to.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top