NSubstitute
NSubstitute copied to clipboard
Is there a way of automatically auto generate mocks for a service?
Question Hello, I am trying to find a way to automatically generate mocks for a specific service in NSubstitute.
Let's supose we have this code sample below
public class AnyClass : IAnyClass
{
private readonly IService1 _service1;
private readonly IService2 _service2;
private readonly IService3 _service3;
public LegacyPublishFieldMapping(IService1 service1, IService2 service2, IService3 service3)
{
_service1 = service1;
_service2 = service2;
_service3 = service3;
}
//...
}
And its unit test below
public class AnyClassTests
{
private readonly IAnyClass _anyClass;
private readonly IService1 _service1Mock;
private readonly IService2 _service2Mock;
private readonly IService3 _service3Mock;
public AnyClassTests()
{
_service1Mock = Substitute.For<IService1>();
_service2Mock = Substitute.For<IService2>();
_service3Mock = Substitute.For<IService3>();
_anyClass = new AnyClass(_service1Mock, _service2Mock, _service3Mock);
}
[Fact]
[Trait("Category", "UnitTest")]
public void DummyTest()
{
// do whatever
}
}
Is there a way for not manually defining each AnyClass dependency (IService1 , IService2, etc)?
It is possible for NSubstitue to build AnyClass instance and automatically inject the mocked services ((IService1 , IService2, etc) like AutoMocker does?
Take a look at AutoFixture. The purpose of AutoFixture is to work like this. AutoFixture does not know how to create interfaces. For this it relies on some kind of plugin libraries. There is one for NSubstitue.
With AutoFixture configured to use NSubstitute, you can re-write your test like this:
public class AnyClassTests
{
[Theory]
[Trait("Category", "UnitTest")]
[AutoNSubstituteData]
public void DummyTest(AnyClass anyClass)
{
// do whatever
}
}
Basically AutoFixture looks at the constructor, sees that the 3 services are need and creates them with the help of NSubstitute.
That works nice for tests where you dont care about any of these services, e.g. testing a guard clause of a method.
The main thing you need to know is that always when AutoFixture sees the demand to create an interface, it will create a new instance of it. To stick to one instance you need to pin this one. In AutoFixture terminoligy this is called freezing. So you must freeze a service instance to test it.
Lets say you want to configure a method/property or assert that some method was called in the IService3 instance.
public class AnyClassTests
{
[Theory]
[Trait("Category", "UnitTest")]
[AutoNSubstituteData]
public void DummyTest([Frozen] IService3 service3, AnyClass anyClass)
{
// Setup the service3 substitute
// do whatever
// assert service3 method was calld with the right parameters
}
}
I think the question has been answered and therefore I will close this one. (Thanks for the answer @Ergamon!)
Please let us know if you need further information or would like us to take another look at this