Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

RDI causes Exception with NSubstitute
JulienN
#1 Posted : Monday, March 18, 2024 2:42:40 PM(UTC)
Rank: Newbie

Groups: Registered
Joined: 2/28/2023(UTC)
Posts: 4
Location: France

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)

Code:
 var exception  = Substitute.For<Exception>();
 var stackTrace = "...");
 //...
 exception.StackTrace.Returns(stackTrace);
 exception.GetBaseException().Returns(exception);


Exception is :
Quote:
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)
Remco
#2 Posted : Monday, March 18, 2024 8:20:35 PM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 6,997

Thanks: 932 times
Was thanked: 1258 time(s) in 1171 post(s)
Hi, thanks for sharing this issue.

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.
JulienN
#3 Posted : Tuesday, March 19, 2024 3:36:18 PM(UTC)
Rank: Newbie

Groups: Registered
Joined: 2/28/2023(UTC)
Posts: 4
Location: France

Hello,

I'll see if I can find the time to create a project from scratch.

Until then, here a the full, buildable test file :

Code:
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 :
Quote:
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.

Correct use:
mySub.SomeMethod().Returns(returnValue);

Potentially problematic use:
mySub.SomeMethod().Returns(ConfigOtherSub());
Instead try:
var returnValue = ConfigOtherSub();
mySub.SomeMethod().Returns(returnValue);

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

Context is :
* .NET 8.0
* Visual Studio 2022 17.9.2
* NCrunch 5.3.0.2
* NUnit 4.0.1
* NSubstitute 5.1.0
* Microsoft.NET.Test.Sdk 17.8.0






Remco
#4 Posted : Tuesday, March 19, 2024 8:01:28 PM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 6,997

Thanks: 932 times
Was thanked: 1258 time(s) in 1171 post(s)
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.
Users browsing this topic
Guest
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

YAF | YAF © 2003-2011, Yet Another Forum.NET
This page was generated in 0.038 seconds.
Trial NCrunch
Take NCrunch for a spin
Do your fingers a favour and supercharge your testing workflow
Free Download