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

时间:2015-09-18 13:57:44

标签: 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 DoSomething(){
        var res = base.DoSomething();
        if(res)
            Messages.Add("Hello World");
        return res;
    }
}

我正在测试的主题是Bar,测试框架是Moq。

        [TestMethod]
        public void TestBar()
        {

            var mockedBar= new Mock<Bar>() {CallBase = true};
            mockedBar.SetupGet(x => x.Messages).Returns(new List<string>());
            mockedBar.Setup(x => x.DoSomething()).Returns(false);

            var result = mockedBar.Object.DoSomething();

            Assert.IsFalse(result, "This should fail");
            mockedBar.Verify(x => x.DoSomething(), Times.Once, "The base DoSomething is called only once.");
         }

我刚刚开始投资单元测试,我不确定我是否正确地进行了测试。 问题:

  1. 现在正在过去,但我对自己的测试方法并不自信。 mockedBar.Setup(x=>x.DoSomething())应设置base.DoSomething()来电。这是对的吗?

  2. 如何测试Bar.DoSomething()实际填充Messages课程中的Foo

  3. 非常感谢任何指导。

2 个答案:

答案 0 :(得分:1)

在这种情况下,我认为你不需要模拟,只需创建一个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"));
}

我们只在需要stub or mock 外部依赖时创建模拟。在您的情况下,您没有任何外部依赖关系来模拟。

答案 1 :(得分:1)

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

mockedBar.Setup(x => x.DoSomething()).Returns(false);
var result = mockedBar.Object.DoSomething();
Assert.IsFalse(result, "This should fail");

所以这实际上并没有调用或测试你的代码。

对于这里的示例,我要么根本不使用mocking,只是测试整个堆栈,或者如果你可以改变你正在测试的代码,我会看看使用依赖注入来删除这个继承。

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