Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NUnit 3.0 and Assert.Throws

I am writing some unit tests with NUnit 3.0 and, unlike v2.x, ExpectedException() has been removed from the library.

Based on this answer, I can definitely see the logic in trying to catch specifically where in the test one expects their system to throw an exception (rather than just saying 'anywhere in the test').

However, I tend to be very explicit about my Arrange, Act, and Assert steps and this makes it a challenge.

I used to do something like:

[Test, ExpectedException(typeof(FormatException))] public void Should_not_convert_from_prinergy_date_time_sample1() {     //Arrange     string testDate = "20121123120122";      //Act     testDate.FromPrinergyDateTime();      //Assert     Assert.Fail("FromPrinergyDateTime should throw an exception parsing invalid input."); } 

Now I need to do something like:

[Test] public void Should_not_convert_from_prinergy_date_time_sample2() {     //Arrange     string testDate = "20121123120122";      //Act/Assert     Assert.Throws<FormatException>(() => testDate.FromPrinergyDateTime()); } 

This isn't terrible, but muddies the Act and Assert, in my opinion. (Obviously, for this simple test, it's not hard to follow, but might be more challenging in larger tests).

I've had a colleague suggest I get rid of Assert.Throws altogether and just do something like:

[Test] public void Should_not_convert_from_prinergy_date_time_sample3() {     //Arrange     int exceptions = 0;     string testDate = "20121123120122";      //Act     try     {         testDate.FromPrinergyDateTime();     }     catch (FormatException) { exceptions++;}      //Assert     Assert.AreEqual(1, exceptions); } 

Here, I stick with the strict AAA format, but at the expense of even more bloat.

So my question goes out to AAA-style testers: How would you do some sort of exception validation testing like I am trying to do here?

like image 342
Killnine Avatar asked Nov 24 '15 15:11

Killnine


People also ask

What Assert throws?

Assert. Throws returns the exception that's thrown which lets you assert on the exception. var ex = Assert.

Does Assert throw exception?

Assertions are used for coding errors (this method doesn't accept nulls, and the developer passed one anyway). For libraries with public classes, throw exceptions on the public methods (because it makes sense to do so). Assertions are used to catch YOUR mistakes, not theirs.

How do I throw an exception in NUnit?

Throws "attempts to invoke a code snippet, represented as a delegate, in order to verify that it throws a particular exception." The () => DoSomething() syntax represents a lambda, essentially an anonymous method. So in this case, we are telling Assert. Throws to execute the snippet o. Foo() .

What is Assert in NUnit?

Assertions are central to unit testing in any of the xUnit frameworks, and NUnit is no exception. NUnit provides a rich set of assertions as static methods of the Assert class. If an assertion fails, the method call does not return and an error is reported.


1 Answers

I see where you're coming from, even though I don't mind combining Act/Assert steps in this case.

The only thing I can think of is to store the actual delegate (here to FromPrinergyDateTime) into a variable as the "act" step and then assert it:

[Test] public void Should_not_convert_from_prinergy_date_time_sample2() {     //Arrange     string testDate = "20121123120122";      //Act     ActualValueDelegate<object> testDelegate = () => testDate.FromPrinergyDateTime();      //Assert     Assert.That(testDelegate, Throws.TypeOf<FormatException>()); } 

I get that the "act" step isn't really acting, but rather defining what the action is. However, it does clearly delineate what action is being tested.

like image 142
Patrick Quirk Avatar answered Oct 04 '22 05:10

Patrick Quirk