Is there any built-in way in NSubstitute for mocking a class with its instance except for few methods?
In example I want to preserve the whole functionality of the instance, but check if a method gets called with particular parameters.
To do that actually I do
public class Wrapper: IInterface
{
public IInterface real;
public IInterface sub;
public void Wrapper(IIterface realInstance, IIterface nsubstitute)
{
real = realInstance;
sub = nsubstitute;
}
public void MethodThatShouldWorkAsAlways()
{
real.MethodThatShouldWorkAsAlways();
}
public intMethodToBeTested(int a)
{
return sub.MethodToBeTested();
}
}
The reason for that is that I'm testing stuff complex enough that I can't simply create wrappers manually, that's time consuming and error-prone. It would be nice if Nsubstitute allows for something like:
IIterface realMock = NSubstitute.Mock< IIterface>( new RealClass());
realMock.MethodThatShouldWorkAsAlways(); // regular logic
realMock.MethodToBeTested(4).Returns( 3); // overrides the method to always returns 3
but I did not find any documentation for doing that so far.
NSubstitute can't mock static methods, so if you want to use NSub for this you'll need to rewrite the original class, or wrap the functionality in a new class that you can mock.
NSubstitute is a friendly substitute for . NET mocking libraries. It has a simple, succinct syntax to help developers write clearer tests. NSubstitute is designed for Arrange-Act-Assert (AAA) testing and with Test Driven Development (TDD) in mind. Product.
The basic syntax for creating a substitute is: var substitute = Substitute. For<ISomeInterface>(); This is how you'll normally create substitutes for types.
If I'm understanding your situation correctly, you have a class you're testing which takes the IIterface
as a dependency and you want to ensure the MethodToBeTested(int)
method is being called by the class you're testing.
This can be done using the .ForPartsOf<T>()
method of generating the mock. This generates a "partial mock", which will call the underlying class implementation unless you provide an override. It comes with a big requirement, though: The methods you want to override (or ensure were called) must be virtual
(or abstract
if defined in a base class).
Once you have the mock, then you can use .Received()
to assert that methods on the mock were called (or not called, if you use .DidNotReceive()
).
You don't actually need to override the behavior of MethodToBeTested(int)
if you want the base implementation to be used.
Here's a concrete example, based on your sample code:
For the dependency, you have a RealClass
that implements the interface IIterface
and you want to ensure MethodToBeTested(int)
was called. So those might look like this:
public interface IIterface
{
void MethodThatShouldWorkAsAlways();
int MethodToBeTested(int a);
}
public class RealClass: IIterface
{
public void MethodThatShouldWorkAsAlways()
{ }
public virtual int MethodToBeTested(int a)
{ return a; }
}
Then you have the class you're actually testing, which uses the IIterface
as a dependency:
public class ClassThatUsesMockedClass
{
private readonly IIterface _other;
public ClassThatUsesMockedClass(IIterface other)
{
_other = other;
}
public void DoSomeStuff()
{
_other.MethodThatShouldWorkAsAlways();
_other.MethodToBeTested(5);
}
}
Now, you want to test that DoSomeStuff()
actually calls MethodToBeTested()
, so you'll need to create a partial mock of SomeClass
and then use .Received()
to validate it was called:
[Test]
public void TestThatDoSomeStuffCallsMethodToBeTested()
{
//Create your mock and class being tested
IIterface realMock = Substitute.ForPartsOf<RealClass>();
var classBeingTested = new ClassThatUsesMockedClass(realMock);
//Call the method you're testing
classBeingTested.DoSomeStuff();
//Assert that MethodToBeTested was actually called
realMock.Received().MethodToBeTested(Arg.Any<int>());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With