NSubstitute is an invaluable tool for .NET developers, offering a streamlined approach to creating test doubles for complex systems. It can easily create mocks not only for interfaces, but also for object. It has quite intelligible documentation, but some of their use cases are not fully covered. Inheritance of multiple interfaces, for example.
Creating Substitutes for Multi-Interface Objects with NSubstitute
NSubstitute provides a seamless way to create substitutes for objects that implement multiple interfaces. Let's explore the steps involved in this process.
Step 1: Define the Interfaces
First, define the interfaces that the object implements. For example, consider an object that implements IFoo
and IBar
interfaces.
public interface IFoo
{
string FooMethod();
}
public interface IBar
{
string BarMethod();
}
Step 2: Create a substitute
NSubstitute allows you to specify multiple interfaces when creating a substitute:
var multiInterfaceSubstitute = Substitute.For<IFoo, IBar>();
var substitute = Substitute.For<IFoo, IBar>();
Assert.True(substitute is IFoo);
Assert.True(substitute is IBar);
Step 3: Configure the Behavior
To configure substitute behaviour you can try use it as you always do:
substitute.FooMethod().Returns("Foo response");
substitute.BarMethod().Returns("Bar response");
No. This wouldn’t compile:
C# compiler is absolutely sure, that your object substitute is only type of IFoo. But not an IBar. I spent some time pondering around this error and was ready to just implement interface that inherits them both. But maybe I wasn’t the first person in the world who encounter this? Unfortunately, Google, StackOverflow and even bing didn’t give me the answer, but with some testing and trying I got this elegant (no) solution:
substitute.FooMethod().Returns("Foo!");
((IBar)substitute).BarMethod().Returns("Bar!");
Assert.Equal("Bar!", ((IBar)substitute).BarMethod());
Other things to play around:
You can implement one known class and set of interfaces there:
[Fact]
public void Test2()
{
var substitute = Substitute.For<MyClass, IFoo, IBar>()!;
Assert.True(substitute is IBar);
((IBar)substitute).BarMethod().Returns("Bar!");
Assert.Equal("Bar!", ((IBar)substitute).BarMethod());
}
Let’s try it with classes.
var substitute = Substitute.For<MyClass, NotMyClass>()!;
This doesn’t work and raises the exceptions:
Tests.UnitTest1.Test4 (< 1ms): Error Message: NSubstitute.Exceptions.SubstituteException : Can not substitute for multiple classes. To substitute for multiple types only one type can be a concrete class; other types can only be interfaces.
So, unfortunately for some c++ folks, there is no multiple inheritance here.
Top comments (0)