简体   繁体   中英

How to mock protected method with NSubstitute

public static void Mock(out IProgram prog, out IJson json)
{    
    prog = Substitute.For<IProgram>();
    IJson = Substitute.For<IJson>();

    prog.SaveProg(1, 1, 1, "Somthing", 1, DateTime.UtcNow,
                 (DateTime.UtcNow + TimeSpan.FromDays(10)), 
                 10, "someemail@email.com", DateTime.UtcNow, 1)
        .Returns(ObjectResult<int?>); 
}

I'm getting an error when calling Returns(ObjectResult<int?>) because ObjectResult is protected class. How can I work around this to be able to call my mocked method from the actual method?

You shouldn't be able to mock a protected class/method.

But you actually can! (at least for methods and properties)

NSubstitute overrides the behavior of a method of a substitute after you have invoked that method, but it actually does not care how you have invoked that method. This allows you to call it via reflection.

Below is a very detailed example:

public class SomeRepository
{
    public string ReadData() => ActuallyPerformDataReading();
    protected virtual string ActuallyPerformDataReading() => "some wrong data";
}

public class SomeClass
{
    SomeRepository _someRepository;
    public SomeClass(SomeRepository someRepository)
    {
        _someRepository = someRepository;
    }

    public string ReadSomething() => _someRepository.ReadData();
}


var repositorySub = Substitute.For<SomeRepository>();
repositorySub.GetType().GetMethod("ActuallyPerformDataReading", BindingFlags.NonPublic | BindingFlags.Instance)
    .Invoke(repositorySub, new object[] {}).Returns("some test data");
var sut = new SomeClass(repositorySub);

var result = sut.ReadSomething(); //"some test data"

You shouldn't be able to mock a protected class/method. It's protected explicitly so you can't do that. If you need to mock it, make it public. If it's someone else's method and you think you need to mock it, you're probably testing incorrectly.

Edit: Any functionality in a protected method can only be used by a public method in that same class. Mock that public method to act however you want given some desired result from the protected method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM