You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
Properties from a substitute object are empty when accessing in a Received.InOrder bloc. It will be clear checking the tests below.
To Reproduce
This is the simplest end-to-end example that I could get the same behaviour.
public interface IMyClass
{
public Uri Uri { get; set; }
}
public interface IMyService
{
public IMyClass GetMyClassAsync();
public void PassUri(Uri uri);
}
public class SystemUnderTest
{
private readonly IMyService service;
public SystemUnderTest(IMyService service)
{
this.service = service;
}
public void Execute()
{
var myClass = service.GetMyClassAsync();
service.PassUri(myClass.Uri);
}
}
The following
public class ReceivedInOrderTests
{
private readonly IMyClass myClass = Substitute.For<IMyClass>();
private readonly IMyService myService = Substitute.For<IMyService>();
private readonly SystemUnderTest sut;
public ReceivedInOrderTests()
{
myClass.Uri.Returns(new Uri("https://test.com"));
myService.Configure().GetMyClassAsync().ReturnsForAnyArgs(myClass);
sut = new SystemUnderTest(myService);
}
// This works fine
[Fact]
public void PassMyClass_WithoutReceivedInOrder_ShouldValidateAllCalls()
{
// Arrange
// Act
sut.Execute();
// Assert
myService.Received(1).GetMyClassAsync();
myService.Received(1).PassUri(Arg.Is<Uri>(uri => uri == myClass.Uri));
}
// This doesn't work
[Fact]
public void PassMyClass_WithReceivedInOrder_ShouldValidateOrderOfCalls()
{
// Arrange
// Act
sut.Execute();
// Assert
Received.InOrder(() =>
{
myService.GetMyClassAsync();
// myClass.Uri is null right here
myService.PassUri(myClass.Uri);
});
// this works and assets that myClass.Uri is not null outside the Received.InOrder bloc
myClass.Uri.ShouldNotBeNull();
}
}
What happens is that inside the property myClass.Uri inside Received.InOrder is null. For some reason the properties from the substitute object are being cleared when testing inside the Receive.InOrder.
*** Note: calls to property getters are not considered part of the query. ***
at NSubstitute.Core.SequenceChecking.SequenceInOrderAssertion.Assert(IQueryResults queryResult)
at NSubstitute.Received.InOrder(Action calls)
at Vincotte.ViA.Storage.UnitTests.ReceivedInOrderTests.PassMyClass_WithReceivedInOrder_ShouldValidateOrderOfCalls()
It doesn't happens when I implement a concrete class, below will you find the example:
public class MyClass : IMyClass
{
public Uri Uri { get; set; }
}
The new test:
[Fact]
public void PassMyClass_WithConcreteMyClass_ShouldValidateOrderOfCalls()
{
// Arrange
var myConcreteClass = new MyClass
{
Uri = new Uri("https://test.com")
};
myService.Configure().GetMyClassAsync().ReturnsForAnyArgs(myConcreteClass);
// Act
sut.Execute();
// Assert
Received.InOrder(() =>
{
myService.GetMyClassAsync();
// Works just fine
myService.PassUri(myConcreteClass.Uri);
});
myClass.Uri.ShouldNotBeNull();
}
Expected behaviour
Success
Environment:
NSubstitute version: 5.1.0
NSubstitute.Analyzers version: CSharp 1.0.16
Platform: dotnet6.0 project on Mac
Feel free to ask more questions if the explanation is not enough.
The text was updated successfully, but these errors were encountered:
Describe the bug
Properties from a substitute object are empty when accessing in a Received.InOrder bloc. It will be clear checking the tests below.
To Reproduce
This is the simplest end-to-end example that I could get the same behaviour.
The following
What happens is that inside the property myClass.Uri inside
Received.InOrder
is null. For some reason the properties from the substitute object are being cleared when testing inside theReceive.InOrder
.Actual behaviour
It doesn't happens when I implement a concrete class, below will you find the example:
The new test:
Expected behaviour
Success
Environment:
Feel free to ask more questions if the explanation is not enough.
The text was updated successfully, but these errors were encountered: