Unit testing massively benefits from following the Arrange / Act / Assert pattern. I’ve seen tests that are not written in this way, and they can be sprawling and indecipherable, either testing many different things in series, or testing nothing at all except the .Net Framework.
I recently found an issue while trying to test for an exception being thrown, which is that Nunit (and probably other frameworks) test for an exception by accepting a delegate to test. Here’s an example:
[Test]
public void Test\_ThrowException\_ExceptionThrown()
{
// Arrange
TestClass tc = new TestClass();
// Act / Assert
Assert.Throws(typeof(Exception), tc.ThrowException);
}
We’re just testing a dummy class:
public class TestClass
{
public void ThrowException()
{
throw new Exception("MyException");
}
}
C# 7 - Inline functions
If you look in the references at the bottom, you’ll see something more akin to this approach:
public void Test\_ThrowException\_ExceptionThrown2()
{
// Arrange
TestClass tc = new TestClass();
// Act
TestDelegate throwException = () => tc.ThrowException();
// Assert
Assert.Throws(typeof(Exception), throwException);
}
However, since C# 7, the option on a local function has arrived. The following has the same effect:
[Test]
public void Test\_ThrowException\_ExceptionThrown3()
{
// Arrange
TestClass tc = new TestClass();
// Act
void CallThrowException()
{
tc.ThrowException();
}
// Assert
Assert.Throws(typeof(Exception), CallThrowException);
}
I think that I, personally, still prefer the anonymous function for this; however, the local function does present some options; for example:
[Test]
public void Test\_ThrowException\_ExceptionThrown4()
{
void CallThrowException()
{
// Arrange
TestClass tc = new TestClass();
// Act
tc.ThrowException();
}
// Assert
Assert.Throws(typeof(Exception), CallThrowException);
}
Now I’m not so sure that I still prefer the anonymous function.
References
http://stackoverflow.com/questions/33897323/nunit-3-0-and-assert-throws
https://pmbanugo.wordpress.com/2014/06/16/exception-testing-pattern/