nsubstitute / NSubstitute

A friendly substitute for .NET mocking libraries.
https://nsubstitute.github.io
Other
2.64k stars 259 forks source link

Clear configured call #821

Open velvolue opened 2 months ago

velvolue commented 2 months ago

Is your feature request related to a problem? Please describe. I configure and use the same mock across a test collection and some tests needs to mutate that mock to set a different return value. After that test is done, I want to reset the mock to the previous behavior. Clearing all configurations is not sufficient as I need to keep the previously configured return value.

Describe the solution you'd like I'd like to be able to use the returned ConfiguredCall to clear just that configuration.

Describe alternatives you've considered The only alternative I see is to replace the mock by manually implementing a fake, but that would require a lot of code to replace all the functionality (received calls etc.).

Additional context This would be a really nice improvement for many use-cases where you share a mock between tests.

Some example code to explain the use-case:

[Collection("myCollection")]
public class ArchiveGridDevelopmentPlanTests(MyTestFixture fixture)
{
    [Fact]
    public void Should_call_service()
    {
        var configuredCall = fixture.MockedService.GetValue().Returns(123);
        try
        {
            var sut = new ClassToTest(fixture.MockedService);
            sut.CallService().Should().Return(123);
        }
        finally
        {
            // It would be nice if this was possible...
            fixture.MockedService.RemoveConfiguredCall(configuredCall);
        }
    }
}
GeraldLx commented 2 months ago

Perhaps the example does not show everything needed, but if you just want some pre defined substitute that can be customized in your tests, you could change MockedService to GetMockedService?

velvolue commented 2 months ago

Yeah, the example is not 100%. MockedService is actually registered as a singleton in an IoC container and used for DI throughout an ASP.NET application so I need to mutate the same substitute.

dtchepak commented 1 month ago

Hi @velvolue ,

New calls to Returns will overwrite existing configurations. Can you overwrite it to call the base implementation instead? The most recently configuration will be used.

Clearing just something for that call sounds reasonable but is tricky to implement as we can match calls using dynamic conditions (Arg.Is() etc).