C# 用Moq对继承层次结构进行单元测试

C# 用Moq对继承层次结构进行单元测试,c#,unit-testing,testing,moq,C#,Unit Testing,Testing,Moq,我有一个继承层次结构,如下所示: public class Foo{ public virtual IList<string> Messages{get;set;} } public class Foo2: Foo{ public bool DoSomething(){ //Evaluate something; } } public class Bar: Foo2{ public override bool DoSomet

我有一个继承层次结构,如下所示:

public class Foo{
        public virtual IList<string> Messages{get;set;}
}

public class Foo2: Foo{
    public bool DoSomething(){
        //Evaluate something;
    }
}

public class Bar: Foo2{
    public override bool DoSomething(){
        var res = base.DoSomething();
        if(res)
            Messages.Add("Hello World");
        return res;
    }
}
我刚刚开始投资单元测试,我不确定我是否做得正确。 问题:

  • 这是通过现在,但我不相信我的测试方法。
    mockedBar.Setup(x=>x.DoSomething())
    应该设置我的
    base.DoSomething()
    调用。对吗

  • 如何测试
    Bar.DoSomething()
    是否实际填充
    Foo
    类中的
    消息


  • 非常感谢您的指导

    在这种情况下,我认为您不需要模拟,只需创建一个
    Bar
    对象并正常测试即可

    [TestMethod]
    public void TestBar()
    {
         var bar = new Bar();
         var result = bar.DoSomething();
         Assert.IsFalse(result, "This should fail");
         //I assume that this is your logic.
         Assert.IsTrue(bar.Messages.Contains("Hello World"));
    }
    

    我们只在需要外部依赖项时创建模拟。在您的情况下,您没有任何要模拟的外部依赖项。

    您正在设置一个模拟,然后使用以下代码调用同一个模拟:

    mockedBar.Setup(x => x.DoSomething()).Returns(false);
    var result = mockedBar.Object.DoSomething();
    Assert.IsFalse(result, "This should fail");
    
    所以这实际上并不是调用或测试代码

    对于这里的示例,我要么根本不使用模拟,只测试整个堆栈,要么如果您可以更改正在测试的代码,我将考虑使用依赖项注入来删除此继承


    使用继承来共享代码会使测试更加困难。

    模拟要测试的对象是没有意义的。通常,您只模拟要测试的对象的依赖关系。回答您的第一个问题:不,安装程序没有设置基本方法,而是最终对象的方法,这是一个模拟Bar的方法。我实际上遵循了这一点。是的,但那篇文章的作者调用的方法与他设置的不同。您正在尝试设置覆盖并只调用base的方法。我正在测试
    Bar
    。那么,
    Foo
    Foo2
    不是外部依赖吗?@Ashish Shakya:我不这么认为。继承是一种关系。非
    具有
    关系(
    具有外部依赖关系
    )。继承的属性成为对象本身的一部分,当
    Foo
    Foo2
    中的任何更改在
    Bar
    中破坏您的代码时,单元测试应该会检测到。感谢您确认我的想法。我担心我根本没有测试任何东西。我还将研究DI解决方案。非常感谢。
    mockedBar.Setup(x => x.DoSomething()).Returns(false);
    var result = mockedBar.Object.DoSomething();
    Assert.IsFalse(result, "This should fail");