- Getting started
- Creating a substitute
- Setting a return value
- Return for specific args
- Return for any args
- Return from a function
- Multiple return values
- Replacing return values
- Checking received calls
- Clearing received calls
- Argument matchers
- Callbacks, void calls and When..Do
- Throwing exceptions
- Safe configuration and overlapping calls
- Raising events
- Auto and recursive mocks
- Setting out and ref args
- Actions with argument matchers
- Checking call order
- Partial subs and test spies
- Return for all calls of a type
- Threading
- Compatibility argument matchers
- NSubstitute.Analyzers
- How NSubstitute works
- Search
Creating a substitute
The basic syntax for creating a substitute is:
var substitute = Substitute.For<ISomeInterface>();
This is how you’ll normally create substitutes for types. Generally this type will be an interface, but you can also substitute classes in cases of emergency.
Substituting (infrequently and carefully) for classes
⚠️ Warning: Substituting for classes can have some nasty side-effects!
For starters, NSubstitute can only work with virtual members of the class that are overridable in the test assembly, so any non-virtual code in the class will actually execute! If you try to substitute for a class that formats your hard drive in the constructor or in a non-virtual property setter then you’re asking for trouble. By overridable we mean public virtual
, protected virtual
, protected internal virtual
, or internal virtual
with InternalsVisibleTo
attribute applied (although to configure or assert on calls members will also need to be callable from the test assembly, so public virtual
or internal virtual
with InternalsVisibleTo
). See How NSubstitute works for more information.
It also means features like Received()
, Returns()
, Arg.Is()
, Arg.Any()
and When()..Do()
will not work with these non-overridable members. For example: subClass.Received().NonVirtualCall()
will not actually run an assertion (it will always pass, even if there are no calls to NonVirtualCall()
), and can even cause confusing problems with later tests. These features will work correctly with virtual members of the class, but we have to be careful to avoid the non-virtual ones.
For these reasons we strongly recommend using NSubstitute.Analyzers to detect these cases, and sticking to substituting for interfaces as much as possible. (Interfaces are always safe to substitute and do not suffer from any of the limitations that class substitutes do.)
With the knowledge that we’re not going to be substituting for classes, here is how you create a substitute for a class that has constructor arguments:
var someClass = Substitute.For<SomeClassWithCtorArgs>(5, "hello world");
For classes that have default constructors the syntax is the same as substituting for interfaces.
Substituting for multiple interfaces
There are times when you want to substitute for multiple types. The best example of this is when you have code that works with a type, then checks whether it implements IDisposable
and disposes of it if it doesn’t.
var command = Substitute.For<ICommand, IDisposable>();
var runner = new CommandRunner(command);
runner.RunCommand();
command.Received().Execute();
((IDisposable)command).Received().Dispose();
Your substitute can implement several types this way, but remember you can only implement a maximum of one class. You can specify as many interfaces as you like, but only one of these can be a class. The most flexible way of creating substitutes for multiple types is using this overload:
var substitute = Substitute.For(
new[] { typeof(ICommand), typeof(ISomeInterface), typeof(SomeClassWithCtorArgs) },
new object[] { 5, "hello world" }
);
Assert.IsInstanceOf<ICommand>(substitute);
Assert.IsInstanceOf<ISomeInterface>(substitute);
Assert.IsInstanceOf<SomeClassWithCtorArgs>(substitute);
Substituting for delegates
NSubstitute can also substitute for delegate types by using Substiute.For<T>()
. When substituting for delegate types you will not be able to get the substitute to implement additional interfaces or classes.
var func = Substitute.For<Func<string>>();
func().Returns("hello");
Assert.AreEqual("hello", func());
Partial substitutes and test spies
When required we can also create substitutes that run real code by default, letting us replace specific parts of a class with substitute behaviour.
Edit this page