简体   繁体   English

这是集成测试还是单元测试?

[英]Is this an Integration Test or a Unit Test?

More than a practical case, this is a question I have when trying to get a detailed difference between Unit Tests and Integration Tests. 不仅仅是一个实际案例,这是我在试图获得单元测试和集成测试之间的详细差异时遇到的问题。

Lets say I have class Sum, which adds two integers: 假设我有类Sum,它增加了两个整数:

class Sum{
  int x;
  int y;
  public int add(){
    return x + y;
  }
  ...getters and setters...
}

And I have another class that is in charge of validate the results, to confirm that the values are the expected. 我还有另一个负责验证结果的类,以确认值是预期的。 Just for the example, let's say we want to add only positive numbers: 仅举例来说,假设我们只想添加正数:

class ValidateSum{
   Sum sum;
   public boolean validate(){
      if(sum.getX()>=0 and sum.getY()>=0){
          return true;
      }
      else{
          return false;
      }
   }
   ... getters and setters...
}

Probably it doesn't make a lot of sense to have ValidateSum, but lets just assume it for the sake of the example. 拥有ValidateSum可能没有多大意义,但我们只是为了举例而假设它。

And now I want to write tests for ValidateSum. 现在我想为ValidateSum编写测试。 If I do this: 如果我这样做:

@Test
public void testValidateSum(){
    ValidateSum vs = new ValidateSum();
    Sum sum = new Sum();
    vs.setSum(sum);
    boolean result = vs.validate();

    assertTrue(result);
}

Is that an Unit Test or an Integration Test? 这是单元测试还是集成测试?

I know that the unit test only has to validate the functionality in ValidateSum, and in a way the test is doing it: It only gets properties from Sum, and not really any of its functionality. 我知道单元测试只需验证ValidateSum中的功能,并且在某种程度上测试是这样做的:它只从Sum获取属性,而不是它的任何功能。

But on the other side, you can also say that you do are accessing functionality from Sum, even if ValidateSum only calls a getter. 但另一方面,你也可以说你正在从Sum访问功能,即使ValidateSum只调用getter。 Any change in Sum's getters would impact the tests for ValidateSum, breaking the concept of Unit Tests. Sum的getter的任何变化都会影响ValidateSum的测试,打破了单元测试的概念。

But if this is the case and indeed it is an Integration Test, then how can I write an Unit Test for ValudateMethod's validate() ? 如果是这种情况并且确实是集成测试,那么我如何为ValudateMethod的validate()编写单元测试

The only thing I can't think of is mocking Sum, so it alwas returns the same value. 我唯一想不到的是嘲笑Sum,所以它返回相同的值。 And even if the logic inside Sum's getter changes, the test for ValidateSum would remain intact. 即使Sum的getter中的逻辑发生变化,ValidateSum的测试也将保持不变。 The problem is that mocking responses of getters could be adding unnecessary complexity since the probability for changes to the logic inside a getter is very low, and all we are doing is getting a property. 问题是,getter的模拟响应可能会增加不必要的复杂性,因为getter中逻辑更改的可能性非常低,而我们所做的只是获取属性。

I hope that my question makes sense, which is more of a theoretical doubt. 我希望我的问题有道理,这更多是理论上的疑问。

Edit 编辑

Thank you for your answers. 谢谢您的回答。 They have important things to have in mind. 他们有重要的事情需要考虑。 The one I selected as the best answer was because it lead me to this: 我选择的最佳答案之一是因为它引导我:

http://www.mockobjects.com/2007/04/test-smell-everything-is-mocked.html http://www.mockobjects.com/2007/04/test-smell-everything-is-mocked.html

And its true: Theoretically I would have to mock Sum so it becomes a pure Unit Test. 它是真的:从理论上讲,我必须模拟Sum,这样才能成为一个纯粹的单元测试。 But for most of the cases, the cost of the complexity added and the effort spent in mocking properties getters are not worth just to get a "purest" unit test, when in practice for this case the difference between Unit and Integration test is subjective. 但是对于大多数情况来说,增加复杂性的成本以及模拟属性获取者所花费的精力并不值得进行“最纯粹的”单元测试,而在实际情况下,单元和集成测试之间的差异是主观的。

Don't mock Sum . 不要嘲笑Sum Getters and setters in general don't have logic. 一般来说,吸气剂和制定者没有逻辑。 Mocking is the process of removing a class's logic so that it doesn't interfere with another class's tests. 模拟是删除类逻辑的过程,因此它不会干扰另一个类的测试。 Mocking a class without any logic, or a class whose logic is not involved with the current test is pointless. 模拟没有任何逻辑的类,或者逻辑与当前测试无关的类是没有意义的。 In fact, "don't mock value objects" is a well known principle of unit testing. 事实上,“不要模拟价值对象”是众所周知的单元测试原则。

Your test is not using any of the logic of the Sum class. 您的测试不使用Sum类的任何逻辑。 So it's a unit test. 所以这是一个单元测试。

But if this is the case and indeed it is an Integration Test, then how can I write an Unit Test for ValudateMethod's validate()? 但如果是这种情况并且确实是集成测试,那么我如何为ValudateMethod的validate()编写单元测试?

Simply by 简单地说

(...) mocking Sum, so it always returns the same value. (...)模拟Sum,所以它总是返回相同的值。

The line between integration and unit is often hard to draw. 集成和单元之间的界限通常很难划分。 But let's try to do that, starting with: 但是,让我们尝试这样做,从:

Integration tests will test interactions between multiple components . 集成测试将测试多个组件之间的交互。

What is a component then? 那么什么是组件? In most cases -- business entity, a class with some logic required to making your software run. 在大多数情况下 - 业务实体,一个具有运行软件所需的逻辑的类。

How does the Sum class fit in here? Sum类如何适应这里? Does it contain business logic essential to make your software run? 它是否包含使软件运行至关重要的业务逻辑? If so, having it not mocked would make your test integrating one (if we stick to the simple definition above). 如果是这样,如果没有嘲笑它会使你的测试整合一个(如果我们坚持上面的简单定义)。

However, Sum class could be just as well a class storing values, having little business logic -- a data structure , if you will. 但是, Sum类也可以是一个存储值的类,具有很少的业务逻辑 - 数据结构 ,如果你愿意的话。 Business entities operate on data structures all the time: integers , strings , Points , Addresses -- all data structures, not requiring any integration to be done. 业务实体始终对数据结构进行操作: integersstringsPointsAddresses - 所有数据结构,不需要进行任何集成。

Classification is up to you and responsibilities you assign to your classes. 分类取决于您和您分配给您的课程的职责。 Interacting with data structures doesn't need integration. 与数据结构交互不需要集成。 Interacting with other business entities might. 与其他业务实体交互可能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM