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.
Leave A Comment