C# 集成测试应该重做使用模拟的单元测试吗?

C# 集成测试应该重做使用模拟的单元测试吗?,c#,unit-testing,tdd,C#,Unit Testing,Tdd,在编写单元测试时,我一次只检查一个类。若我需要使用额外的类,那个么我将使用模拟来确保测试是独立的 稍后我想编写集成测试,我是否应该复制/粘贴所有使用模拟的单元测试,并在删除模拟对象后测试它们 示例代码: public class Event { string title; List<Hour> hoursList = new List<Hour>(); public Event(string title) { this.title = title;

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

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

示例代码:

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 */  }
}
公共类事件
{
字符串标题;
List hoursList=新列表();
公共事件(字符串标题){this.title=title;}
public void AddHour(Hour newHour){hoursList.Add(newHour);}
public int HourCount(){return hoursList.Count;}
公共整数TotalDuration(){
int-total=0;
foreach(小时列表中的var小时)
总计+=小时。GetDuration();
返回总数;
}
}
公共课时
{
字符串开始;
弦端;
公共小时(字符串开始,字符串结束){this.start=start;this.end=end;}
公共虚拟int GetDuration(){/*algorightm以分钟为单位计算持续时间*/}
}
示例测试:

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());
int预期值=165;
活动音乐会=新活动(“本地乐队音乐会”);
模拟ehMock=新模拟(“07:00”、“08:30”);
Setup(x=>x.GetDuration()).Returns(90);
模拟ehMock2=新模拟(“19:15”、“20:30”);
设置(x=>x.GetDuration())。返回(75);
Concert.AddHour(ehMock.Object);
Concert.AddHour(ehMock2.Object);
Assert.AreEqual(预期为Concert.TotalDuration());
在上面的单元测试中,我从事件类测试TotalDurationmethod,Hour类被模拟,我重写了GetDuration()方法。现在,我应该使用相同的测试进行集成测试,但不使用Mock吗


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

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

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

单元测试用于测试单个单元的所有方面。所有装置,所有功能。进行隔离测试。换句话说:你构建了一大堆乐高积木,单元测试告诉你所有这些积木都能完成它们应该做的事情

另一方面:集成测试可以简化以确保正确的集成。意思是:你想出了你最重要的“路径”,你想被采纳,然后你编写了集成/功能测试来解决这些问题

本文的要点是保留单元测试,以便编写数量少得多的集成测试。因为单元测试运行得很快,可以帮助您快速识别和修复bug。集成测试更为重要,但是 更昂贵*,并且您只能将它们用于无法正确进行单元测试的事情


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

这个问题的答案将相当严重地基于观点,因此它们不适合堆栈溢出。我建议将此问题提交给或堆栈交换。@Abion47谢谢您的评论,我将检查提到的堆栈。我感谢您的快速回复!我通常应该避免向模拟构造函数传递参数,还是可以借助[TestCase()]属性来实现这一点?有些对象需要在构造函数中输入数据,所以我假设有一些很好的方法可以做到这一点。我已经更新了上面的示例,现在它涵盖了更高级的情况。