简体   繁体   English

如何使用 NSubstitute 模拟受保护的方法

[英]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.调用Returns(ObjectResult<int?>)时出现错误,因为ObjectResult是受保护的类。 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. NSubstitute 会在您调用该方法后覆盖替代方法的行为,但它实际上并不关心您是如何调用该方法的。 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.模拟该公共方法的行为,但您希望从受保护的方法中获得一些所需的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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