- 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
Auto and recursive mocks
Once a substitute has been created some properties and methods will automatically return non-null values. For example, any properties or methods that return an interface, delegate, or purely virtual class* will automatically return substitutes themselves. This is commonly referred to as recursive mocking, and can be useful because you can avoid explicitly creating each substitute, which means less code. Other types, like String
and Array
, will default to returning empty values rather than nulls.
* Note: A pure virtual class is defined as one with all its public methods and properties defined as virtual or abstract and with a default, parameterless constructor defined as public or protected.
Recursive mocks
Say we have the following types:
public interface INumberParser {
IEnumerable<int> Parse(string expression);
}
public interface INumberParserFactory {
INumberParser Create(char delimiter);
}
We want to configure our INumberParserFactory
to create a parser that will return a certain set of int
for an expresion
. We could manually create each substitute:
var factory = Substitute.For<INumberParserFactory>();
var parser = Substitute.For<INumberParser>();
factory.Create(',').Returns(parser);
parser.Parse("an expression").Returns(new[] {1,2,3});
Assert.AreEqual(
factory.Create(',').Parse("an expression"),
new[] {1,2,3});
Or we could use the fact that a substitute for type INumberParser
will automatically be returned for INumberParserFactory.Create()
:
var factory = Substitute.For<INumberParserFactory>();
factory.Create(',').Parse("an expression").Returns(new[] {1,2,3});
Assert.AreEqual(
factory.Create(',').Parse("an expression"),
new[] {1,2,3});
Each time a recursively-subbed property or method is called with the same arguments it will return the same substitute. If a method is called with different arguments a new substitute will be returned.
var firstCall = factory.Create(',');
var secondCall = factory.Create(',');
var thirdCallWithDiffArg = factory.Create('x');
Assert.AreSame(firstCall, secondCall);
Assert.AreNotSame(firstCall, thirdCallWithDiffArg);
Note: Recursive substitutes will not be created for non-purely virtual classes, as creating and using classes can have potentially unwanted side-effects. You’ll therefore need to create and return these explicitly.
Substitute chains
It is not really an ideal practice, but when required we can also use recursive mocks to make it easier to set up chains of substitutes. For example:
public interface IContext {
IRequest CurrentRequest { get; }
}
public interface IRequest {
IIdentity Identity { get; }
IIdentity NewIdentity(string name);
}
public interface IIdentity {
string Name { get; }
string[] Roles();
}
To get the identity of the CurrentRequest
to return a certain name, we could manually create substitutes for IContext
, IRequest
, and IIdentity
, and then use Returns()
to chain these substitutes together. Instead we can use the substitutes automatically created for each property and method:
var context = Substitute.For<IContext>();
context.CurrentRequest.Identity.Name.Returns("My pet fish Eric");
Assert.AreEqual(
"My pet fish Eric",
context.CurrentRequest.Identity.Name);
Here CurrentRequest
is automatically going to return a substitute for IRequest
, and the IRequest
substitute will automatically return a substitute for IIdentity
.
Note: Setting up long chains of substitutes this way is a code smell: we are breaking the Law of Demeter, which says objects should only talk to their immediate neighbours, not reach into their neighbours’ neighbours. If you write your tests without recursive mocks this becomes quite obvious as the set up becomes quite complicated, so if you are going to use recursive mocking you’ll need to be extra vigilant to avoid this type of coupling.
Auto values
Properties and methods returning types of String
or Array
will automatically get empty, non-null defaults. This can help avoid null reference exceptions in cases where you just need a reference returned but don’t care about its specific properties.
var identity = Substitute.For<IIdentity>();
Assert.AreEqual(String.Empty, identity.Name);
Assert.AreEqual(0, identity.Roles().Length);