Feb 10
2009Testing for Expected Exceptions Without Compromising BDD Conventions
Filed Under (.Net, Unit Testing) by John Miller on 10-02-2009
Tagged Under : .Net, BDD, C#, Unit Testing
Today I decided to relearn some of the BDD concepts I picked up at the end of last year and ran into a scenario where I needed to test that a specific type of exception was being thrown by a method. The simple way to do this is to decorate your test method with an ExpectedException attribute, but that forces you to combine the Act/Assert parts of your test.
Not happy with that solution I decided that I would rather catch the exception in one part of my test and validate it’s type later. In the end, I created a helper class to do some of the work:
public class ExceptionTestHelper{public static Exception CatchException(Action action){try{action.Invoke();}catch (Exception ex){return ex;}return null;}}
Pretty simple. And now our tests seem a little more natural.
[TestFixture]public class When_asked_to_get_a_users_goals_using_an_invalid_user_id: GoalsServiceTestBase{private Exception caughtException;protected override void because(){base.because();caughtException =ExceptionTestHelper.CatchException(() => goalsService.GetGoalsForUser(-1));}[Test]public void should_throw_an_argument_exception(){Assert.That(caughtException,Is.InstanceOfType(typeof(ArgumentException)));}}
public abstract class GoalsServiceTestBase : TestBase{protected IGoalsRepository stubGoalsRepository;protected IGoalsService goalsService;protected Goal stubGoal;protected override void establish_context(){base.establish_context();stubGoalsRepository =MockRepository.GenerateStub<IGoalsRepository>();goalsService = new GoalsService(stubGoalsRepository);stubGoal = new Goal();}}
[TestFixture]public abstract class TestBase{[SetUp]public void setup(){establish_context();because();}protected virtual void establish_context(){ }protected virtual void because(){ }}
At first glance I like it. Although I’m sure that someone out there that may have a better solution that still sticks with our BDD approach.

/>
