Nsubstitute: How to Substitute.ForPartsOf<MyClass> when MyClass requires parameters in instantiation?

Created on 10 Mar 2020  路  2Comments  路  Source: nsubstitute/NSubstitute

Question
I'm trying to unit test a method (Method1) in a class (MyClass). One thing Method1 does is calls Method2 (also a MyClass method) which hits an external API. Obviously, I'd like to substitute the API response, so my initial thought is to use a Substitute.ForPartsOf. However, the MyClass constructor requires three parameters for instantiation, which I have substituted as _i1, _i2, and _i3.

How can I instantiate / substitute MyClass in a way that I can provide the constructor parameters _i1, _si2, and _i3, mock a result for Method2, and test Method1?

public class MyClass : IMyClass
{
    private readonly Interface1 _i1;
    private readonly Interface2 _i2;
    private readonly Interface3 _i3;

    public MyClass(Interface1 i1, Interface2 i2, Interface3 i3)
    {
        _i1 = i1;
        _i2 = i2;
        _i3 = i3;
    }

    public async Task<OtherClass> Method1(ClassA classAObj, bool boolObj, string stringObj)
    {
        // do some stuff here
        otherClassObj.Property = Method2(classAObj.property1, stringObj);
        // do some more stuff
        return otherClassObj;
    }

    public async Task<List<AnotherClass>> Method2(int intObj, string stringObj)
    {
        // do some API stuff
    }

}

I want to substitute for Method 2 when testing Method 1, but I need to be able to provide i1, i2, and i3 in the instantiation of MyClass.

question

All 2 comments

@CleveSteve Substitute.ForPartsOf<T>() has the overload which allows you to pass constructor parameters when creating a substitute
```c#
using NSubstitute;
using Xunit;

namespace MyNamespace
{
public class MyClass
{
public int X { get; }
public int Y { get; }

    public MyClass(int x, int y)
    {
        X = x;
        Y = y;
    }
}

public class FooTests
{
    [Fact]
    public void Foo()
    {
        var substitute = Substitute.ForPartsOf<MyClass>(1, 2);
    }
}

}
`` When it comes to the testing part, in order to substituteMethod2it would have to be virtual one. If that is the change you willing to make, you can then use theConfiguresyntax (for NSubstitute 4.x) orWhen ... DoNotCallBase` for older ones as described in docs

@CleveSteve closing this one as the solution above should work for you. In case you have any questions feel free to reopen

Was this page helpful?
0 / 5 - 0 ratings