Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Substitute.ForPartsOf() usage -- or Alternative? #608

Closed
CleveSteve opened this issue Jan 24, 2020 · 3 comments
Closed

Substitute.ForPartsOf() usage -- or Alternative? #608

CleveSteve opened this issue Jan 24, 2020 · 3 comments

Comments

@CleveSteve
Copy link

CleveSteve commented Jan 24, 2020

I have a method (MethodA) I'm trying to test (of course) and I'd like to substitute a method (MethodC) that is called inside of the method (MethodA) being tested like this...

public async MethodA(CustomClass myInfo, bool myBool)
{
    ... await stuff
    paramVal1 = MethodB(paramVal1, myInfo, myBool);
    ...morestuff
}

public DifferentCustomClass MethodB(DifferentCustomClass paramVal1, CustomClass myInfo, bool myBool)
{
    ...stuff
    paramVal1.PropertyZ = MethodC(myInfo, myBool);
    ...stuff
    return paramVal1;
}

Methods A, B, and C are all in the same class.

Is there any way I can use NSubstitute to give a .Returns(value) for MethodC when testing MethodA? I tried Substitute.ForPartsOf with .Configure().MethodC(val1, val2).Returns(val0) with and without .When(x => x.MethodC(val1, val2)).DoNotCallBase() to no avail.

Is it clear what I am trying to do here? Is there a way this can be implemented in NSubstitute? Thanks.

@CleveSteve
Copy link
Author

never mind... I realized I'm trying to substitute something that is non-virtual anyways... I've gotta just add to the constructor... ugh. Great tool though, thank you.

@dtchepak
Copy link
Member

dtchepak commented Jan 25, 2020

@CleveSteve Glad you got it sorted. If you need more info try the partial subs documentation.

Another option rather than a partial sub (which calls base implementations by default), is using a normal sub and opting-in to calling base on some members:

public class Example
{
    public virtual string Repeat(string s, int times) {
        return String.Join(" ", Enumerable.Repeat(s, times));
    }

    public virtual string Hi(string name) => $"Hi {name}";
}

[Fact]
public void Sample() {
    var sub = Substitute.For<Example>();
    sub.Repeat("", 0).ReturnsForAnyArgs(x => "stub");
    sub.WhenForAnyArgs(x => x.Hi("")).CallBase();

    var resultFromCallingBase = sub.Hi("World");
    var stubbedResult = sub.Repeat("asfd", 42);

    Assert.Equal(resultFromCallingBase, "Hi World");
    Assert.Equal(stubbedResult, "stub");
}

Sometimes that's easier than using DoNotCallBase() on calls.

@CleveSteve
Copy link
Author

Very Cool! Missed that option somehow. Thanks for the reply.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants