We have a series of tests that uses NSubstitute to override some properties in an Exception in order to test one of our extension method.
This code works properly without RDI enabled, but fails with an exception when RDI is enabled (NCrunch v5.3.0.2)
var exception = Substitute.For<Exception>();
var stackTrace = "...");
//...
exception.StackTrace.Returns(stackTrace);
exception.GetBaseException().Returns(exception);
Exception is :
NSubstitute.Exceptions.CouldNotSetReturnDueToTypeMismatchException : Can not return value of type ExceptionProxy for Exception.get_StackTrace (expected type String).
Make sure you called Returns() after calling your substitute (for example: mySub.SomeMethod().Returns(value)),
and that you are not configuring other substitutes within Returns() (for example, avoid this: mySub.SomeMethod().Returns(ConfigOtherSub())).
(+more a lot of suggestions on how to use NSubstitute)
Are you able to build a full code sample that can reproduce this problem? I've tried using the short example you've given me, but I can't seem to make it happen.
My theory is that the RDI instrumentation is somehow interfering with NSubstitue. There were some issues with this early in development, though I thought we had it all nailed down. I guess there must be a case that we're not handling right in here.
It should be possible to work around this issue by using RDI inline directives to switch off RDI in these code blocks, but I'd like to see if there's a way we can handle this out of the box.
I'll see if I can find the time to create a project from scratch.
Until then, here a the full, buildable test file :
using NSubstitute;
namespace Namespace;
public class ExtensionsTest
{
[Test]
public void Test()
{
var exception = Substitute.For<Exception>();
exception.GetBaseException().Returns(exception); //<--- Exception here
Assert.That(exception.GetBaseException(), Is.EqualTo(exception));
}
}
The full stacktrace :
NSubstitute.Exceptions.CouldNotSetReturnDueToTypeMismatchException : Can not return value of type ExceptionProxy for Exception.get_StackTrace (expected type String).
Make sure you called Returns() after calling your substitute (for example: mySub.SomeMethod().Returns(value)),
and that you are not configuring other substitutes within Returns() (for example, avoid this: mySub.SomeMethod().Returns(ConfigOtherSub())).
If you substituted for a class rather than an interface, check that the call to your substitute was on a virtual/abstract member.
Return values cannot be configured for non-virtual/non-abstract members.
at NSubstitute.Core.ConfigureCall.CheckResultIsCompatibleWithCall(IReturn valueToReturn, ICallSpecification spec)
at NSubstitute.Core.ConfigureCall.SetResultForLastCall(IReturn valueToReturn, MatchArgs matchArgs, PendingSpecificationInfo pendingSpecInfo)
at NSubstitute.Core.CallRouter.LastCallShouldReturn(IReturn returnValue, MatchArgs matchArgs, PendingSpecificationInfo pendingSpecInfo)
at NSubstitute.Core.ThreadLocalContext.LastCallShouldReturn(IReturn value, MatchArgs matchArgs)
at NSubstitute.SubstituteExtensions.ConfigureReturn[T](MatchArgs matchArgs, T returnThis, T[] returnThese)
at NSubstitute.SubstituteExtensions.Returns[T](T value, T returnThis, T[] returnThese)
at Namespace.ExtensionsTest.Test() in ExtensionsTest.cs:line 12
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
Note that we are not using StackTrace, though the exception is mentioning it.
I tried disabling/enabling RDI, restarting the VS, it is always the same exception on get_StackTrace
Strangely, this code seems to work fine for me when I build a sample identical to what you've described. There must be a component I'm missing here. Please do let me know if you manage to set up a self contained solution that can produce this. You can submit small code samples through the NCrunch contact form.