java - 如何在 Java 单元测试中模拟接口(interface)?

标签 java unit-testing junit mocking mockito

我正在尝试为以下方法创建单元测试:

public List<CompanyUserDTO> findAllByUserUuidIn(final Set<UUID> userUuidList) {
        return companyUserRepository.findAllByUserUuidIn(userUuidList);
    }

此方法返回作为接口(interface)的CompanyUserDTO列表。接口(interface)定义如下:

public interface CompanyUserDTO {
    UUID getUserUuid();

    UUID getCompanyUuid();

    String getCompanyName();

    default CompanyDTO getCompany() {
        return new CompanyDTO(getCompanyUuid(), getCompanyName());
    }
}

这是CompanyDTO:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class CompanyDTO {
    private UUID uuid;
    private String name;

    public CompanyDTO(final Company company) {
        this.uuid = company.getUuid();
        this.name = company.getName();
    }
}

我的单元测试如下所示:

@Test
public void test_findAllByUserUuidIn() {
    Set<UUID> userUuidList = new HashSet<>();
    userUuidList.add(UUID.fromString("00000000-0000-0000-0000-000000000001"));
    userUuidList.add(UUID.fromString("00000000-0000-0000-0000-000000000002"));
    userUuidList.add(UUID.fromString("00000000-0000-0000-0000-000000000003"));

    // --> here I need a mock list of `CompanyUserDTO`
    List<CompanyUserDTO> companyUserDTOList = new ArrayList<>();

    when(companyUserRepository.findAllByUserUuidIn(userUuidList))
        .thenReturn(companyUserDTOList);

    List<CompanyUserDTO> result = companyUserService
        .findAllByUserUuidIn(userUuidList);

    assertEquals(companyUserDTOList, result);
}

1. 那么,我应该如何在测试中创建 CompanyUserDTO 的模拟列表?

2.我的单元测试适合这种方法吗?

最佳答案

  1. 您不需要模拟,只需创建对象本身(我猜您至少有一个 CompanyUserDTO 接口(interface)的实现)。
  2. 其他一切都很好,尽管您的方法没有那么多逻辑需要测试。

鉴于您没有 CompanyUserDTO 的实现,您可能会使用匿名类来避免实现本身,但仅用于测试目的。您可以按如下方式进行:

@Test
public void test_findAllByUserUuidIn() {
    // Arrange
    Set<UUID> userUuidList = new HashSet<>();
    userUuidList.add(UUID.fromString("00000000-0000-0000-0000-000000000001"));
    userUuidList.add(UUID.fromString("00000000-0000-0000-0000-000000000002"));
    userUuidList.add(UUID.fromString("00000000-0000-0000-0000-000000000003"));

    CompanyUserDTO companyUserDTO = new CompanyUserDTO() {
        @Override
        public UUID getUserUuid() {
            return UUID.randomUUID();
        }
        
        @Override
        public UUID getCompanyUuid() {
            return UUID.randomUUID();
        }

        @Override
        public String getCompanyName() {
            return "Company Name Test";
        }
    };
    List<CompanyUserDTO> companyUserDTOList = new ArrayList<>();
    companyUserDTOList.add(companyUserDTO);

    when(companyUserRepository.findAllByUserUuidIn(userUuidList))
        .thenReturn(companyUserDTOList);

    // Act
    List<CompanyUserDTO> result = companyUserService
        .findAllByUserUuidIn(userUuidList);

    // Assert
    assertEquals(companyUserDTOList, result);
}

如果您希望避免匿名类,那么您需要在 test 源包中创建以下类:

public class CompanyUserDTOImpl implements CompanyUserDTO {
    @Override
    public UUID getUserUuid() {
        return UUID.randomUUID();
    }
    
    @Override
    public UUID getCompanyUuid() {
        return UUID.randomUUID();
    }

    @Override
    public String getCompanyName() {
        return "Company Name Test";
    }
};

然后你的测试就会变得更简单:

@Test
public void test_findAllByUserUuidIn() {
    // Arrange
    Set<UUID> userUuidList = new HashSet<>();
    userUuidList.add(UUID.fromString("00000000-0000-0000-0000-000000000001"));
    userUuidList.add(UUID.fromString("00000000-0000-0000-0000-000000000002"));
    userUuidList.add(UUID.fromString("00000000-0000-0000-0000-000000000003"));

    List<CompanyUserDTO> companyUserDTOList = new ArrayList<>();
    companyUserDTOList.add(new CompanyUserDTOImpl());

    when(companyUserRepository.findAllByUserUuidIn(userUuidList))
        .thenReturn(companyUserDTOList);

    // Act
    List<CompanyUserDTO> result = companyUserService
        .findAllByUserUuidIn(userUuidList);

    // Assert
    assertEquals(companyUserDTOList, result);
}

关于java - 如何在 Java 单元测试中模拟接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70020551/

相关文章:

java - 重定向到新 URL 时小程序崩溃

node.js - 你如何使用 testdouble 模拟 typeorm 的 getManager?

c++ - Visual Studio native 单元测试 : Debug/console output?

php - 在单元测试类中断言困境

java - 在没有显式测试套件类声明的情况下清理所有 JUnit 测试

java - 从Java中的另一个类访问变量的实例

java - 如何选择SD卡中的文件?

java - 从 Function<V, R> 使用 compose() 或 andThen() 时返回对象

java - 同一对象的 JUnit 测试

java - 如何测试java DBMS应用程序的性能