One of my favourite new tools to come across in 2011 is NSubstitute. This a is friendly substitution framework for .net. This will allow me to use these substitutes in place of mocks and stubs. Traditionally I use a mocking framework that requires the use of mocks and stubs. Unfortunately, this type of tool has now become a bit of a hindrance for me. The code that is written to assert behaviour has happened seems complex and is not instantly readable for junior developers. Now this isn’t a tool bashing exercise – this post is to demonstrate that this tool (NSubstitute) has effectively made me see the complexity of my tests. It has made me think about being more expressive in my intent. Its not about the tool itself – its about the concept behind it.
On the commencement of a new project, i tried to show some developers NSubstitute. They liked it – they said on first look it was easy to read test code. I suggested they try it for the new project as it was brand new and had 0 test count. I was immediately shot down due to an apparent “learning curve” and “sticking with what they know”. I understand the learning curve part – learning a new tool is potentially tough as its a real shift in what they know. The apathy of sticking with what they knew really saddens me. If I had this level of apathy, I’d still be working with ASP.NET webforms 2.0 and still not unit testing like I was doing 7 years ago. We should all want to push ourselves a little and move outside our comfort zone in order to mature as professionals. Its effectively how we grow, learn and get better at what we do.
I can understand why a developer would not what to change to a new tool when working in an established project. It would be like a rewrite of a section of the project. It would also take time and money to change. But when it is a brand new project with no current toolset what is the issue? Seems a little strange to me.
From my investigations about this topic of mocks and stubs vs. fakes / substitutes, I have seen that there is a real lack of understanding of the differences between mocks and stubs. This article will not talk about the differences – Martin Fowler has already done this in his article Mocks aren’t stubs and there is no way I could do it the justice he has. This has really led me to the question do we really need to care about the differences of mocks and stubs when we have this level of complexity in our tests?. As a developer who tries to push testing to a team, all I want to do is to take an object or a class and test that some logic or behaviour has happened and I get the correct result. We don’t want to shouldn’t make this difficult for ourselves by trying to decide if the object or class that we want should be a mock or a stub.
I have heard of people who get this concept so mixed up that they try and verify all expectations against stubs so they get passing unit tests when this is of course not correct. This is to show sample of implementation of that test.
This shows a test with mocking and stubbing to check that specific behaviour has happened
The same behaviour using substitutes / fakes to demonstrate how much easier it can be without the layer of complexity (written by Dave Tchepak from NSubstitute). Dave did point out that other tools can drive this expressive type of test and also he could write complex looking tests with NSubstitute as well.
I’m not the first developer to talk about this topic and I’m certainly not the last. I think it’s a topic that requires buy in/ backing from a host of developers who lead the way. When talking about this on twitter, Hadi Hariri said the following:
“People need to understand the difference between state and interaction testing, not stubs/mocks/fakes/dupes/blabla”
This is very true! Let’s remove this barrier of complexity in our tests and learn how to write better tests. It doesn’t matter which tool we use to do it. Join me in trying to get developers to take the plunge!