It is 2018, and I have only just learned about the fantastic FluentAssertions framework. Seems like a nice time for a quick review of unit testing tools for .NET. Personal preferences: NUnit, FluentAssertions, Moq.
MSTest, NUnit, XUnit - they are all useful. They are all well-integrated into Visual Studio now. I would not make a strong argument against any choice for a team that already knows the tool. For new development, I would unhesitatingly choose NUnit.
I used XUnit for the FlightNode project. I enjoyed the flexibility with the assertion statements. I did not like the enforcement of only one assertion per unit test. The theory is that multiple assertions make it more difficult to know which thing failed (do yourself a favor and add a message in the assertion to solve this!) and you do not get verification on the assertions written below the one that failed. The latter is a valid point, but I have very rarely found this to be a problem in the real world. Ultimately, I ended up spending too much time writing method signatures and extracting shared functionality in the name of small tests with one assertion. I also found that my XUnit tests were hard to maintain as the style caused me to extract so much into private functions, thus reducing the readability of any individual test.
MSTest at this point might be as good as NUnit - I have not investigated in a long time. The unit test first mentality of NUnit and its strong testing of exceptions and async make me a believer. Also, while Microsoft is a great company and all… I like promoting a diverse ecosystem.
- This style helps me think about the value I’m testing first, rather than thinking about the assertion statement first
- It is easier to read.
- The assertion error messages are beautiful.
- The breadth and depth of the syntax is awe-inspiring.
Trivial comparison from an XUnit test
Assert.Equal(expected, system.Body); /* Message: Assert.Equal() Failure Expected: hi Actual: (null) */
system.Body.Should().Be(expected); /* Message: Expected system.Body to be "hi", but found <null>. */
Moq is hands-down the winner. NSubstitute looks interesting and might be viable competition; however, it has been around for 8 years and personally I’ve never run into a project that uses it. RhinoMocks was great in its time, I’m sure, but the syntax is not as nice as Moq. And while the founder’s personal repository has had a handful of commits in recent years, the official repo hasn’t seen a commit since 2010 - whereas Moq is very much alive, with multiple releases in 2018. Ancient. And slow. Old code that still uses RhinoMocks should be updated.
A Note on
Looking back at FlightNode, I was confused by some code I wrote two years ago. What is this
Fixture.Freeze code about? Apparently I have completely forgotten about AutoFixture. It was probably an interesting experiment. It may have even been beneficial. But I do not even know what’s going on when I look at my own tests. No doubt a quick review of AutoFixture’s documentation would suffice to bring me up to speed. At this moment, I have no argument for or against it.