How to suppress exceptions with fluent assertions

Imagine you need to code the following requirements:

  • When an exception is thrown the transaction must be rolled back
  • The thrown exception must be rethrown

The productive code could look like:

public class SomeComponent
{
   public void Do() {
      ITransaction tx = this.session.BeginTransaction();
      try {
      this.session.Save(foo);
      } catch(DataException e) {
         tx.Rollback();
         throw;
      }
   }
}

Now how would you write the requirements above in two separate unit tests? Here comes FluentAssertions into the play.

We just write a little extension method which ignores a specific kind of exception type and hook it up just after the fluent assertions extension method “Invoking”.

    public static class CustomAssertionExtensions
    {
        public static void IgnoreAnyExceptions<TException>(this Action action)
            where TException : Exception
        {
            try
            {
                action();
            }
            catch(TException)
            {
            }
        }
    }

And here the test code which uses it.

    [TestFixture]
    public class SomeComponentTest
    {
        private ITransaction transaction;
        private ISession session;
        private SomeComponent testee;

        [SetUp]
        public void SetUp()
        {
            this.transaction = A.Fake<ITransaction>();
            this.session = A.Fake<ISession>();
            this.SetupSessionReturnsTransaction();

            this.testee = new SomeComponent(this.session);
        }

        [Test]
        public void WhenExceptionOccurs_ShouldRollbackTransaction()
        {
            A.CallTo(() => this.session.Save(A<object>.Ignored)).Throws(new DataException());

            this.testee.Invoking(t => t.Execute()).IgnoreAnyExceptions<DataException>();

            A.CallTo(() => this.transaction.Rollback()).MustHaveHappened();
        }

        [Test]
        public void WhenExceptionOccurs_ShouldRethrow()
        {
            A.CallTo(() => this.session.Save(A<object>.Ignored)).Throws(new DataException());

            this.testee.Invoking(t => t.Execute()).ShouldThrow<DataException>();
        }

        private void SetupSessionReturnsTransaction()
        {
            A.CallTo(() => this.session.BeginTransaction()).Returns(this.transaction);
        }
    }

Hope this helps. I suggest you check out fluent assertions! Have fun. By the way the example was written using FakeItEasy. Be sure to check it out too!

About the author

Daniel Marbach

Add comment

Recent Posts