Unit testing 单元测试和集成测试示例

Unit testing 单元测试和集成测试示例,unit-testing,integration-testing,database-testing,Unit Testing,Integration Testing,Database Testing,我在一个测试类中创建了以下四个测试,该测试类测试CompanyService的findCompany()方法 @Test public void findCompany_CompanyIdIsZero() { exception.expect(IllegalArgumentException.class); companyService.findCompany(0); } @Test public void findCompany_CompanyIdIsNegative() {

我在一个测试类中创建了以下四个测试,该测试类测试CompanyService的findCompany()方法

@Test
public void findCompany_CompanyIdIsZero() {
    exception.expect(IllegalArgumentException.class);
    companyService.findCompany(0);
}
@Test
public void findCompany_CompanyIdIsNegative() {
    exception.expect(IllegalArgumentException.class);
    companyService.findCompany(-100);
}
@Test
public void findCompany_CompanyIdDoesntExistInDatabase() {
    Company storedCompany = companyService.findCompany(100000);
    assertNull(storedCompany1);
}

@Test
public void findCompany_CompanyIdExistsInDatabase() {
    Company company = new Company("FAL", "Falahaar");

    companyService.addCompany(company);

    Company storedCompany1 = companyService.findCompany(company.getId());
    assertNotNull(storedCompany1);
}
我的理解是,前三个是单元测试。他们测试findCompany()方法的行为,检查该方法如何响应不同的输入。 第四个测试虽然放在同一个类中,但在我看来实际上是一个集成测试。它要求首先将公司添加到数据库中,以便以后可以找到该公司。这引入了外部依赖项-addCompany()和数据库

我走对了吗?如果是,那么我应该如何通过单元测试找到一个现有的对象?只是模仿服务来“找到”一个?我认为这扼杀了测试的意图


我很感激这里的指导。

我这样看:您在这里测试的“单元”是
公司服务。从这个意义上讲,您的所有测试在我看来都像是单元测试。但是,在您的服务下面,可能还有另一个服务(您提到的是数据库),这个测试也在使用它?这可能会使集成测试的界线变得模糊,但你必须问问自己这是否重要。您可以删除任何此类基础服务,如果:

  • 基础服务的设置或使用速度很慢,使单元测试太慢
  • 您希望确保此测试的行为不受基础服务的影响-即,只有当
    CompanyService
    中存在错误时,此测试才会失败

  • 根据我的经验,只要底层服务足够快,我就不会太担心依赖它进行单元测试。我不介意有一点集成泄漏到我的单元测试中,因为它有好处(更多的集成覆盖率),而且很少引起问题。如果它确实导致问题,您可以随时返回到它并添加存根以改进隔离。

    [1,2,3,4]可以是基于单元(模拟的,而不是模拟的)和基于集成的测试。这取决于你想测试什么

    • 为什么要嘲笑?如前所述……只测试服务层,不测试底层
    • 为什么要嘲笑?您的业务逻辑可以有多种形式。因此,您可以为一种服务方法编写多个测试,例如创建个人(无地址-异常,无银行帐户-异常,个人未填写非空属性-异常)
    您能想象每个测试都请求数据库来测试所有可能的异常状态(无地址、无银行帐户等)?为了测试所有异常状态,有太多的工作要填充数据库。为什么不使用模拟对象,例如,行为类似于不包含预期值的“残废”对象。每个测试构造都有自己的“跛脚”模拟对象

    模拟各种状态===您的测试将尽可能简单,因为每个测试方法将只测试一个状态。这些测试将清晰、易于理解和维护。如果我写一个测试,这是我想要达到的目标之一。

    。底层服务(数据库调用)仅仅是Hibernate单行调用,当然不会包含任何bug。所以,我想我正在做的是好的。