Is there a more appropriate to test if the constructor throws an exception?
-
12-06-2021 - |
Question
Normally you test, if an exception gets thrown in a certain method, as follows. I use FluentAssertions:
[Fact]
public void Exception_gets_thrown()
{
// Arrange
var foo = new Foo("validArgument");
// Act/Assert
foo.Invoking(f => f.Bar(null)) // null is an invalid argument
.ShouldThrow<ArgumentNullException>();
}
But how to test, if an exception gets thrown in the constructor? I just did it like this, but is there maybe a more appropriate way via FluentAssertions?
[Fact]
public void Constructor_throws_Exception()
{
// Arrange
Action a = () => new Foo(null); // null is an invalid argument
// Act/Assert
a.ShouldThrow<ArgumentNullException>();
}
Solution
That's exactly how you're supposed to test for exceptions and that's what ShouldThrow<T>()
and ShouldNotThrow<T>()
were designed for in the first place. In fact, the Invoking()
approach might be marked as obsolete in the next big version (2.0.0).
OTHER TIPS
I added a helper method like the below for use when testing constructors:
static Action Constructor<T>(Func<T> func)
{
return () => func();
}
which I then use like this:
Constructor(() => new Foo("bar", null))
.ShouldThrow<ArgumentNullException>()
.And
.ParamName
.Should()
.Be("baz");
I know it's a matter of personal taste, but I find this a bit cleaner than needing to declare and assign a delegate first.
This would make the code in the original question look like this:
[Fact]
public void Constructor_throws_Exception()
{
// Act/Assert
Constructor(() => new Foo(null)).ShouldThrow<ArgumentNullException>();
}
There's a built-in.
FluentActions.Invoking(() => new Foo(null)).ShouldThrow<ArgumentNullException>();