Moq parent 方法在 child class 中被调用

Moq parent method being called in child class

我有一个基 class,它有一个受保护的方法,在我想测试的 child class 的 public 方法中被调用。我没能找到一种方法来最小化基本保护方法以便在 child class.

中进行更轻松的测试
public class MyBaseClass
{
    protected virtual bool MyMethod(int number)
    {
        return number == 1;
    }   
}

public class MyChildClass : MyBaseClass
{
    public bool DoSomething(int number)
    {
        return MyMethod(number);
    }
}

[TestFixture]
public class MyChildClassTests
{
    [Test]
    public void Expected_Returns_False_WhenPassed_1()
    {
        var myChildClass = new MyChildClass();

        // How do I mock MyMethod used in myBaseClass here?
        // var mock = new Mock<MyBaseClass>();
        // mock.Protected().Setup<bool>("MyMethod", ItExpr.IsAny<int>()).Returns(false);
        
        // The above mock is correct, but it's in a different instance object than myBaseClass

        var result = myChildClass.DoSomething();

        Assert.AreEqual(false, result);
    }
}

我无法更改 classes 以获得更好的架构,我必须尽我所能为 DoSomething() 实施单元测试,到目前为止我所做的是模拟和准备该方法使用的所有数据,但由于它在另一个 class 中,我希望我的 MyChildClassTests 不做所有这些,只限于测试 DoSomething().

我已经阅读了有关部分模拟的内容以及大量其他问题和答案,但我无法使其正常工作。

我很感激任何建议!

编辑:忘记在所有 class 中加入 public,在我的真实世界中,它们是 public.

class MyChildClassTests
{
    [Test]
    public void Expected_Returns_False_WhenPassed_1()
    {
        var myChildClass = new FakeChildClass();
        
        var result = myChildClass.DoSomething(1);

        Assert.AreEqual(false, result);
    }
}

public class FakeChildClass: MyChildClass
{
    protected override bool MyMethod(int number)
    {
        return number == 1;
    }
}

首先,确保您的 class 是 public。

如果他们不这样做,Moq 会抱怨无法代理到他们。

public class MyBaseClass
{
    public virtual bool MyMethod(int number)
    {
        return number == 1;
    }   
}

public class MyChildClass : MyBaseClass
{
    public bool DoSomething(int number)
    {
        return MyMethod(number);
    }
}

接下来,制作您的基础 class 方法 public。除非你这样做,否则你将无法设置它。

之后,创建 child 对象的模拟并模拟父方法。

var mockChild = new Mock<MyChildClass>(){CallBase = true};
            mockChild.Setup(x => x.MyMethod(It.IsAny<int>())).Returns(false);

拉出你的结果.... 结果 将 return 为假,即使实际实施将 returned 为真并以 1 作为参数。

var result = mockChild.Object.DoSomething(1);

当调用 DoSomething 方法时,您实际上会进入该方法的真正实现(如果您不相信我,请设置断点!)- 但 MyMethod 的模拟版本将启动。

感谢大家的回复,收集所有我能够得到我的用例的实际答案:

不改变MyBaseClassMyChildClass

public class MyBaseClass
{
    protected virtual bool MyMethod(int number)
    {
        return number == 1;
    }   
}

public class MyChildClass : MyBaseClass
{
    public bool DoSomething(int number)
    {
        return MyMethod(number);
    }
}

我能够模拟受保护的方法并节省大量工作和重复代码(已经在 MyBaseClassTests 中)

[TestFixture]
public class MyChildClassTests
{
    [Test]
    public void Expected_Returns_False_WhenPassed_1()
    {
        var expected = false;
        var myChildClass = new Mock<MyChildClass> {CallBase = true};
        myChildClass.Protected().Setup<bool>("MyMethod", 1).Returns(expected);
        
        var result = myChildClass.Object.DoSomething(1);

        Assert.AreEqual(expected, result);
    }

    [Test]
    public void Expected_Returns_True_WhenPassed_1()
    {
        var expected = true;
        var myChildClass = new Mock<MyChildClass> {CallBase = true};
        myChildClass.Protected().Setup<bool>("MyMethod", 1).Returns(expected);
        
        var result = myChildClass.Object.DoSomething(1);

        Assert.AreEqual(expected, result);
    }
}

感谢大家的帮助! :)