Search code examples
c#unit-testingnsubstitute

NSubstitute - Match parameter then do action and return specific value


I'm a newbie in NSubstitue mocking framework.

I have the following requirements:

  1. Match DoSomething parameter.
  2. Do something (add one of the parameter's fields to myList)
  3. Return a specific value.

The code should look like this:

mockDependency.When(x => x.DoSomething(Arg.Is<string>(s => s == "specificParameter")))
    .Do(x => myList.Add(x.Name))
    .Return("ReturnValue");

The only way I know to meet the requirements above is to do something like this:

mockDependency.When(x => x.DoSomething(Arg.Is<string>(s => s == "specificParameter")).Do(x => myList.Add(x.Name))

Then, configure the return value separately:

mockDependency.DoSomething(Arg.Is<string>(s => s == "specificParameter")).Return(myValue)

Is there a simpler way to achieve the requirements?

I know that in fakeItEasy I can do something like this:

A.CallTo(() => mockDependency.DoSomething(A<string> .That.Matches(x=> x == "specificParameter") )).Invokes(x => myList.Add(x.Name)).Returns(myValue)


Solution

  • You can combine returning a value via Returns with doing an action using AndDoes.

    The string value passed to DoSomething (here: specificParameter) acts as the filter; only when DoSomething gets called with that value, the specified setup of the return value and action will be invoked.

    public class Tests
    {
        [Fact]
        public void Test2()
        {
            var myList = new List<string>();
            var mock = Substitute.For<IWorker>();
    
            mock.DoSomething("specificParameter")
                .Returns("ReturnValue")
                .AndDoes(o => myList.Add(o.ArgAt<string>(0)));
    
            var result = mock.DoSomething("specificParameter");
        }
    }   
    
    public interface IWorker
    {
        string DoSomething(string value);
    }