【问题标题】:Should integration tests redo unit tests that use mocking?集成测试应该重做使用模拟的单元测试吗?
【发布时间】:2018-08-07 19:03:23
【问题描述】:

在编写单元测试时,我一次只检查一个类。如果我需要使用额外的类,那么我将使用模拟来确保测试是独立的。

稍后我想编写集成测试,是否应该只复制/粘贴所有使用模拟的单元测试并在删除模拟对象后对其进行测试?

示例代码:

public class Event
{
    string title;
    List<Hour> hoursList = new List<Hour>();
    public Event(string title) { this.title = title; }
    public void AddHour(Hour newHour) { hoursList.Add(newHour); }
    public int HourCount() { return hoursList.Count; }
    public int TotalDuration() {
        int total = 0;
        foreach (var hour in hoursList)
        total += hour.GetDuration();
        return total;
    }
}
public class Hour
{
    string start;
    string end;
    public Hour(string start, string end) { this.start = start; this.end = end; }
    public virtual int GetDuration() { /* algorightm calculating duration in minutes */  }
}

示例测试:

int expected = 165;
Event Concert = new Event("Local band concert");
Mock<Hour> ehMock = new Mock<Hour>("07:00", "08:30");
ehMock.Setup(x => x.GetDuration()).Returns(90);
Mock<Hour> ehMock2 = new Mock<Hour>("19:15", "20:30");
ehMock2.Setup(x => x.GetDuration()).Returns(75);
Concert.AddHour(ehMock.Object);
Concert.AddHour(ehMock2.Object);
Assert.AreEqual(expected, Concert.TotalDuration());

在上面的单元测试中,我正在测试 Event 类的 TotalDuration 方法,Hour 类被模拟并且我覆盖了 GetDuration() 方法。现在我应该使用相同的测试进行集成测试,但没有 Mock 吗?

也许上面的例子太简单了,不需要集成测试。如果我有更高级的单元测试,那么推荐相同功能的集成测试?

【问题讨论】:

  • 这个问题的答案将是相当基于意见的,因此它们不适合 Stack Overflow。我建议将此问题提交给Software EngineeringSoftware QA and Testing Stack Exchanges。
  • @Abion47 感谢您的评论,我会检查提到的堆栈。
  • 感谢您的快速回归!

标签: c# unit-testing tdd


【解决方案1】:

一个更抽象的答案:这两件事的范围完全不同。

存在单元测试来测试各个单元的所有方面。所有单元,所有功能。单独测试。换句话说:您构建了一大堆乐高积木,而您的单元测试告诉您所有这些构建块完全按照它们应该做的事情。

另一方面:集成测试归结为确保正确的集成。意思是:你想出你最重要的“路径”,你想被采纳,然后你编写集成/功能测试来敲定这些。

testing pyramid 的全部意义在于您保留了单元测试,这样您就可以编写更少数量的集成测试。因为单元测试运行速度很快,并帮助您快速识别和修复错误。集成测试更重要,但也 更昂贵*,并且您将它们用于无法正确进行单元测试的事情。

所以:集成测试当然会“测试”您的单元测试已经验证过的东西。但是您确实想简单地将所有单元测试转变为集成测试。

【讨论】:

    【解决方案2】:

    在这种确切的情况下,由于您没有在ehMock 中设置任何内容,因此您不会从模拟中获得任何收益,因此在没有模拟的情况下进行集成测试也可以做到这一点。此外,向构造函数添加参数(例如“07:00”)意味着您实际上是在反对模拟,因为这一直是一种确切的情况。特长;我将此示例称为集成测试。

    【讨论】:

    • 我通常应该避免将参数传递给 Mock 构造函数,还是可以在 [TestCase()] 属性的帮助下做到这一点?有些对象需要在构造函数中输入数据,所以我认为有一些好的方法可以做到这一点。
    • 我已经更新了上面的例子,现在它涵盖了更高级的情况。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-29
    • 2011-09-01
    相关资源
    最近更新 更多