I'm running unit tests in a class library project with NSpec framework, AutofacContrib.NSubstitute v3.3.2.0, NSubstitute v1.7.0.0 (the latest as of now is 1.8.2).
The Class Under Test instance is built with AutoSubstitute
, in order to automock all its needed dependencies.
AutoSubstitute autoSubstitute = new AutoSubstitute();
MainPanelViewModel viewModel = autoSubstitute.Resolve<MainPanelViewModel>();
If working properly, my Class Under Test at some point will invoke one of it's base class methods with some specific input parameter (the base class is out of my control):
// ...
base.ActivateItem(nextScreen);
// ...
So, for test expectation, I need to check (spy) that the instance invokes the base method:
viewModel.Received().ActivateItem(Arg.Any<SomeSpecificScreenType>());
Here's the problem: when I try to do this, at runtime NSubstitute complains that I can only ran Received()
against an object created with Substitute.For<>()
. I also checked quickly AutofacContrib.NSubstitute source code, but I could not find a way to obtain the instance with automocking and at the same time wrap it somehow in a spy object or something like that.
I also thought that maybe Substitute.ForPartsOf<>()
could be helpful, but that method does not seem to be found in NSubstitute v1.7.0.
For sake of completeness, here's NSubstitute full error:
NSubstitute extension methods like .Received() can only be called on objects created using Substitute.For() and related methods.
ActivateItem
in the base class takes place, rather than checking that the method itself is called (which is essentially an implementation detail). Is there a reason you can't do that?Subsitute.ForPartsOf
might help, but it's generally a bad idea to mock the class you're testing. The method you want to test will also need to be virtual, so without testing it, I'm sceptical that an explicit call to thebase.ActivateItem
would actually trigger the substitute anyway. Testing for what the method does is likely to be easier. – AnchieActivateItem
behaviour would be hard, given that we go into the UI View-land. But then I just recalled that there should also be anActiveItem
property ... so now I'm just going to check that – Pease