Polecam w swoim kodzie rzucać wyjątki z własną wiadomością. Pomaga to podczas diagnostyki problemu, który wystąpił w wdrożonym systemie. Dobrze jest wtedy przetestować, czy rzucamy poprawny wyjątek w problematycznej sytuacji. Framework xUnit posiada własną klasę do przechwytywania wyjątków o nazwie Record. Oferuje ona dwie metody Exception oraz oczywiście ExceptionAsync. Metody te zwracają obiekt typu Exception na którym możemy wykonać asercje.

 

Rys. 1. Struktura projektu

Do solucji TestingPatterns dodałem nowy katalog RecordException oraz plik RecordExceptionTests, w którym znajdzie się przykładowy kod:

using System;
using Xunit;

namespace xUnitFeatures.RecordException
{
    public class RecordExceptionTests
    {
        public void TestMethod()
        {
            throw new NullReferenceException("Oj coś poszło nie tak");
        }

        [Fact]
        public void Should_throw_exception()
        {
            var exception = Record.Exception(() => TestMethod());

            Assert.NotNull(exception);
        }

        [Fact]
        public void Should_throw_exception_NullReferenceException_type()
        {
            var exception = Record.Exception(() => TestMethod());

            Assert.IsAssignableFrom<NullReferenceException>(exception);
        }

        [Fact]
        public void Should_throw_exception_with_message()
        {
            var exception = Record.Exception(() => TestMethod());

            Assert.Equal("Oj coś poszło nie tak", exception.Message);
        }
    }
}

Powyższy przykład mówi sam za siebie. Nie ma tu wiele do tłumaczenia. TestMethod() symuluje nam funkcję w systemie, która rzuca wyjątkiem, gdy poszło coś nie tak. Użycie klasy Record jest bardzo proste. Celowo w testach zamiast skrótu sut (system under tests) używam zmiennej o nazwie exception. Ten zabieg ma na celu zwiększenie czytelności testu.