Serguzest
Serguzest

Reputation: 1307

Are multiple arrangements allowed on the same method with NSubstitute?

I am new to NSubstitute. The test fails because the second arrangement causes invocation of the first one and makes it fail even before the "act". I am not sure if i should make multiple arrangements on the same method. But I feel like It shouldn't be calling the first arrangement regardless, since the parameters don't match.

public interface IMediator
{
    Task<TResponse> Send<TResponse>(IRequest<TResponse> request, CancellationToken cancellationToken = default(CancellationToken));

    Task Send(IRequest request, CancellationToken cancellationToken = default(CancellationToken));

    Task Publish<TNotification>(TNotification notification, CancellationToken cancellationToken = default(CancellationToken))
        where TNotification : INotification;
}

public class MyMessage : IRequest<MyResponse> {}

public class MyResponse {}

public class MyMessage2 : IRequest<MyResponse> {}

    [Fact]
    public async Task Mock_Fail() {
        var mediatr = Substitute.For<IMediator>();
        var myMessage = new MyMessage();
        var myMessage2 = new MyMessage();
        var myResponse = new MyResponse();
        var myResponse2 = new MyResponse();

        mediatr.Send(Arg.Any<MyMessage>())
            .Returns((ci) => {
                Assert.Same(myMessage, ci[0]); //That fails
                return myResponse;
            });

        mediatr.Send(Arg.Any<MyMessage2>())
            .Returns((ci) => {
                return myResponse2;
            });

       //Execution never reaches here
        var response = await mediatr.Send(myMessage);
        var response2 = await mediatr.Send(myMessage2);

    }

Upvotes: 1

Views: 1120

Answers (1)

David Tchepak
David Tchepak

Reputation: 10464

Normally I'd test this more like:

 mediatr.Send(myMessage)
        .Returns(ci => myResponse);

 mediatr.Send(myMessage2)
        .Returns(ci => myResponse2);

There are a few approaches to overriding previous stubs that throw, but I think the best approach is to avoid the problem where possible. :)

EDIT after more info provided: This looks like a bug in NSubstitute's Arg.Any handling. A work around is to use Arg.Is<MyMessage>(x => x!=null) as shown in that issue description. Overall I would focus on stubbing more specifically to avoid the calls overlapping as per my original answer.

Upvotes: 1

Related Questions