C# 代码应该是单元测试还是集成测试

C# 代码应该是单元测试还是集成测试,c#,unit-testing,testing,integration-testing,C#,Unit Testing,Testing,Integration Testing,首先,我是测试新手,所以这可能是一个愚蠢的问题。我目前正在为我的类创建单元测试。我有一个属性,依赖于可为null的属性,它将向数据库发送一个新的注释对象。通常,通过单元测试,我只需确保一个对象被发送到我的模拟服务,并称之为良好的。然而,测试Comment对象上的值以确保它沿着正确的路径运行,而不是仅仅假设它沿着正确的路径运行,这难道不是更有意义吗。以下是我正在测试的代码示例: if (DeliveryDate != null) { AddPartHistory("Delivery Date

首先,我是测试新手,所以这可能是一个愚蠢的问题。我目前正在为我的类创建单元测试。我有一个属性,依赖于可为null的属性,它将向数据库发送一个新的注释对象。通常,通过单元测试,我只需确保一个对象被发送到我的模拟服务,并称之为良好的。然而,测试Comment对象上的值以确保它沿着正确的路径运行,而不是仅仅假设它沿着正确的路径运行,这难道不是更有意义吗。以下是我正在测试的代码示例:

if (DeliveryDate != null)
{
   AddPartHistory("Delivery Date Changed from " + ((DateTime)DeliveryDate).ToShortDateString() + " to " + ((DateTime)value).ToShortDateString());
}
else
{
   AddPartHistory("Delivered Date of " + ((DateTime)value).ToShortDateString() + " was added.");
}
AddPartHistory
函数将注释对象(保存名为Entry的属性中的文本)发送到数据库(或在测试期间发送到模拟服务),并将其存储在名为
NewPartHistory
的属性中。下面是我认为更像是集成测试的代码:

vm.DeliveryDate = DateTime.UtcNow;
Assert.AreEqual("Delivered Date of " + ((DateTime)vm.DeliveryDate).ToShortDateString() + " was added.", vm.NewPartHistory.Entry);

OldDeliveryDate = vm.DeliveryDate;
vm.DeliveryDate = DateTime.UtcNow;
Assert.AreEqual("Delivery Date Changed from " + ((DateTime)OldDeliveryDate).ToShortDateString() + " to " + ((DateTime)vm.DeliveryDate).ToShortDateString(), vm.NewPartHistory.Entry);
那么,回到问题上来,我应该把这段代码留在单元测试中,还是转移到集成测试中

更新: 因为有很多关于我的
AddPartHistory
方法的讨论,这里就是了。它只需填写
零件历史记录的标准数据(始终相同),添加条目,然后用新数据更新
列表视图

private void AddPartHistory(string historyText)
{
   NewPartHistory = new CdaService.PartHistory();
   NewPartHistory.EnteredBy = User.Current.UID;
   NewPartHistory.Entry = historyText;
   NewPartHistory.EntryDate = DateTime.UtcNow;
   NewPartHistory.PartId = ThisPart.Id;
   webService.Insert(NewPartHistory);
   GetPartHistory();
}

我会将其更改为将新的Comment对象传递给AddPartHistory方法,而不是将值传递给它以构建对象。这样,您就可以对逻辑进行单元测试,包括comment对象的构造。从AddPartHistory返回comment对象也会很有帮助,以便更容易断言

将其从方法中移出,如下所示:

   NewPartHistory = new CdaService.PartHistory();
   NewPartHistory.EnteredBy = User.Current.UID;
   NewPartHistory.EntryDate = DateTime.UtcNow;
   NewPartHistory.PartId = ThisPart.Id;

   if()
   {  
      NewPartHistory.Entry = "Delivered Date of"......;
      return AddPartHistory(NewPartHistory );
   }
   else
   {
       NewPartHistory.Entry = "Delivery Date Changed from".....;
       return AddPartHistory(NewPartHistory );
   }

   //return comment object from AddPartHistory so that you can call this entire method and assert all properties

在我看来,你两个都在做,不是吗?你在断言你的预期和实际是他们应该是的,不是吗?对我来说,断言是一种罕见的情况,它不仅可以是单元测试,还可以是集成测试。单元-因为您是一个级别上的单元测试代码,集成-因为您将单元测试与返回的数据进行更深一层的比较。我明白您的意思,但在真正的集成测试中,我实际上会发送到数据库,并正确地检索回来?在大多数情况下,是的,您会这样做。但并非所有情况下都如此。我认为你们实施的机制是相当可靠的。但是,如果您对此有点紧张,您可以随时将注释对象传递给
AddPartHistory
,看看它是如何构造的,也许?我已经在问题中添加了AddPartHistory方法。让我知道你的想法。我想我对单元测试和集成测试之间的区别有点困惑。在50000英尺的视图中(这是非常主观的),单元测试测试一块代码(通常是一个函数/方法)。另一方面,集成测试不仅测试函数/方法,还测试该方法接受什么(如果重载),以及它如何与上面、下面和周围的层交互。您的回答反映了我的评论,+1:)我添加了我的AddPartHistory方法,并解释了为什么使用它,如果你能再详细一点我会很感激的,因为我不完全理解如何实现您所说的内容。@DarylBehrens我建议您从AddPartHistory方法中提取comment对象的构造,以便更好地测试构造。然后您可以将该方法传递给函数,甚至返回它。我真的很抱歉,我不认为这会有什么帮助,无意冒犯。我在视图模型中使用该代码块大约15次。我以前在每个属性设置器中都对其进行硬编码,但我认为对于代码重用,最好使用方法。这对我的单元测试有什么帮助,不管我把stations放在哪里,最终结果都是一样的。再次抱歉,我真的不明白(我的错不是你的错)。