No, it is not generally good practice to use a mocking library in production code. (I'm going to use "generally" a lot here as I think any question on "good practice" will require a degree of generalisation. People may be able to come up with cases that work against this generalisation, but I think those cases will be the vast minority.)
Even without performance considerations, mocking libraries create test implementations for interfaces/classes. Test implementations generally support functions such as recording calls made and stubbing specific calls to return specific results. Generally when we have an interface or class for production code, it is to achieve some specific purpose, not the general purpose of recording calls and stubbing return values.
While it would be possible to provide a specific implementation for an interface using NSubstitute and to stub each call to execute production code logic, why not instead create a class with the required implementations instead?
This will generally have these advantages:
- should be more succinct to implement (if not, consider switching to a better language! :D)
- uses the native constructs of your programming language
- should have better performance (removes levels of indirection required for mocking library)
For NSubstitute specifically there are some big reasons why you should never use it in production code. Because the library is designed for test code it uses some approaches that are unacceptable for production code:
- It uses global state to support its syntax.
- It abuses C#/VB syntax for the purpose of testing (can almost be considered a testing DSL). e.g. say
sub.MyCall()
returns an int
. Stubbing a call like sub.MyCall().Returns(42)
means we are calling int.Returns(42)
, which is now somehow going to influence a return value of a call outside of the int
on which it is being called. This is quite different to how C#/VB generally works.
- It requires virtual members for everything. This constraint is shared by many mocking libraries. For NSubstitute, you can get unpredictable results if you use it with non-virtual members. Unpredictability is not a nice thing to have for production code.
- Tests are generally short-lived. NSubstitute (and probably other libraries) can make implementation decisions that rely on short-lived objects.
- Tests show pass or failure for a particular case. This means if there is a problem in NSubstitute it can be immediately picked up while attempting to write and run a specific test. While a lot of effort goes into NSubstitute quality and reliability, the amount of work and scrutiny the C# compiler goes through is a completely different level. For production code, we want a very stable base to use as a foundation.
In summary: your programming language provides constructs designed and optimised for implementing logical interfaces. Your mocking library provides constructs designed and optimised for the much more limited task of providing test implementations of logical interfaces for use with testing code in isolation from its dependencies. Unless you have an ironclad reason as to why you would do the programming equivalent of digging a hole with a piece of paper instead of a shovel, I'd suggest using each tool for its intended purpose. :)