NSubstitute
NSubstitute copied to clipboard
NSubstitute.Exceptions.SubstituteInternalException
The package itself asked me to raise this issue with the following code:
NSubstitute.Exceptions.SubstituteInternalException
Please report this exception at https://github.com/nsubstitute/NSubstitute/issues:
CallCollection.Delete - collection doesn't contain the call
at NSubstitute.Core.CallCollection.Delete(ICall call)
at NSubstitute.Core.GetCallSpec.<>c__DisplayClass4_0.<FromPendingSpecification>b__1(ICall lastCall)
at NSubstitute.Core.PendingSpecificationInfo.Handle[T](Func`2 onCallSpec, Func`2 onLastCall)
at NSubstitute.Core.GetCallSpec.FromPendingSpecification(MatchArgs matchArgs, PendingSpecificationInfo pendingSpecInfo)
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 BinInspector.Api.UnitTests.LoginEndpointsTests.Login_ShouldCallCorrectMethodWithCorrectParameters() in F:\Repos\BinInspector\BinInspector.Api.UnitTests\UnitTest1.cs:line 25
at Xunit.Sdk.TestInvoker`1.<>c__DisplayClass46_0.<<InvokeTestMethodAsync>b__1>d.MoveNext() in /_/src/xunit.execution/Sdk/Frameworks/Runners/TestInvoker.cs:line 253
--- End of stack trace from previous location ---
at Xunit.Sdk.ExecutionTimer.AggregateAsync(Func`1 asyncAction) in /_/src/xunit.execution/Sdk/Frameworks/ExecutionTimer.cs:line 48
at Xunit.Sdk.ExceptionAggregator.RunAsync(Func`1 code) in /_/src/xunit.core/Sdk/ExceptionAggregator.cs:line 90
To Reproduce I had this test:
[Fact]
public async Task Login_ShouldCallCorrectMethodWithCorrectParameters()
{
// Arrange
var mockDbConnection = Substitute.For<IDbConnection>();
var mockDbTransaction = Substitute.For<IDbTransaction>();
var loginRequest = new LoginRequest("abc", "123");
var expectedUserDetails = new UserDetails("01", "1", "123", "Tester", "abc");
mockDbConnection.QueryFirstOrDefaultAsync<UserDetails>(Arg.Any<string>(), Arg.Any<DynamicParameters>())!.Returns(Task.FromResult(expectedUserDetails));
// Act
var result = await LoginEndpoints.Login(mockDbConnection, loginRequest);
// Assert
await mockDbConnection.Received().QueryFirstOrDefaultAsync<UserDetails>("EXEC [GET_ValidLogin] @EmployeeNumber, @DeviceUUID", Arg.Is<DynamicParameters>(p =>
p.Get<string>("@EmployeeNumber") == loginRequest.EmployeeNumber &&
p.Get<string>("@DeviceUUID") == loginRequest.DeviceUuid));
result.Should().BeEquivalentTo(expectedUserDetails);
}
The IDbConnection is from Dapper.
the actual code being tested is:
using (context)
{
context.Open();
var parameters = new DynamicParameters();
parameters.Add("@EmployeeNumber", request.EmployeeNumber);
parameters.Add("@DeviceUUID", request.DeviceUuid);
var userDetails = await context.QueryFirstOrDefaultAsync<UserDetails>("EXEC [GET_ValidLogin] @EmployeeNumber, @DeviceUUID", parameters);
return userDetails is not null ? TypedResults.Ok(userDetails) : TypedResults.Unauthorized();
}
Just running a stored proc using Dapper. This is just a unit test to ensure parameters are passed in the right order.
Expected behaviour A clear and concise description of what you expected to happen, compared to what actually happened.
Environment:
- NSubstitute version: 5.1.0
- Platform: net8.0 project on windows
Additional context running in VS2022 Version 17.10.0 Preview 1.0