【问题标题】:How to perform Tests for DTOs?如何对 DTO 进行测试?
【发布时间】:2021-03-09 11:05:52
【问题描述】:

我正在创建一个类来存储所有 DTO 类的测试,但目前我只设法覆盖了 coverage 的 10%。我需要知道如何为 DTO 执行 @Tests

我的DTO

@Data
@NoArgsConstructor
public class ActivityDTO {

    private Integer id;

    private Integer version;

    @JsonProperty("working_days")
    private MonthWorkingDays workingDays;

}

我的Test班级:

@Test
    public void ActivityDTOTest() {
        ActivityDTO obj = BeanBuilder.builder(ActivityDTO.class).createRandomBean();
    }

这是coverage

我的问题:我不知道如何测试DTO 类,我正在使用assertEquals 进行测试,但我不知道如何应用它。有人能把这个 DTO 类的 Test 类是什么样的,从而能够在其他类中复制它吗?

【问题讨论】:

  • 你喜欢测试什么?例如,您设置了“版本”并且它拥有该值?
  • 我不知道如何测试 DTO,所以我想知道最常见的测试 DTO 的方法。我想知道在这种情况下将其应用于其他 DTO 的最佳方法。
  • 从设计模式来看,我将 DTO 视为没有行为或功能逻辑的数据的容器。出于这个原因,我认为 DTO 不值得花时间进行测试。话虽如此,您的 DTO 实现了哪些需要测试的逻辑?从您发布的 sn-ps 中,我没有看到任何明显的内容。
  • 在 DTO 中,我存储了一些共享相似实体的字段。我附上了这个DTO覆盖率的截图,这就是我要解决的问题。
  • 我认为这是一个关于如何不使用代码覆盖率的好例子。你看,所有显示 0 覆盖率的方法......都是生成的。担心您自己编写的代码的覆盖率。

标签: spring-boot unit-testing


【解决方案1】:

这可能是主观的,但一般来说,您不应该为了增加覆盖率而进行测试,而应该始终思考测试检查的“究竟是什么”。

简而言之,可以测试两件事:

  • 对象的状态
  • 一种行为

大多数测试通常(可以说,但至少这是我通常在我的项目中所做的)倾向于检查在技术上作为方法内部的业务逻辑实现的行为。

由于DTO并没有真正具有逻辑的方法,所以只能测试对象的状态。

另一个想法:检查你没有写的代码是没有意义的。所以是的,按照您在问题中的示例,放置 lombok 注释将生成一些 getter/setter/constructors - 但它不是您的代码,这些注释的正确处理应该由 lombok 团队本身检查。

如果您真的想测试 DTO,您可以做的是生成具有一些默认值的 DTO,并检查其内部状态是否确实与预期相符。像这样的:

public class ActivityDTO {

    private Integer id;

    private Integer version;

    // getters / setters maybe
}

@Test
public void test_state_is_correct() {
   ActivityDTO underTest  = new ActivityDTO(SAMPLE_ID, SAMPLE_VERSION);
   assertThat(underTest.getId(), equalTo(SAMPLE_ID));
   assertThat(underTest.getVersion(), equalTo(SAMPLE_VERSION));
}

@Test
public void test_equals_two_objects_with_same_values() {
   ActivityDTO underTest  = new ActivityDTO(SAMPLE_ID, SAMPLE_VERSION);
   assertThat(underTest, equalTo(new ActivityDTO(SAMPLE_ID, SAMPLE_VERSION)); 
}

@Test
public void test_equals_two_objects_with_different_id() {
   ActivityDTO underTest  = new ActivityDTO(SAMPLE_ID, SAMPLE_VERSION);
   assertThat(underTest, not(equalTo(new ActivityDTO(ANOTHER_SAMPLE_ID, SAMPLE_VERSION)); 
}


@Test
public void test_equals_two_objects_with_different_version() {
   ActivityDTO underTest  = new ActivityDTO(SAMPLE_ID, SAMPLE_VERSION);
   assertThat(underTest, not(equalTo(new ActivityDTO(SAMPLE_ID, ANOTHER_SAMPLE_VERSION)); 
}

 ... test for toString()... and hashCode maybe, etc.

这肯定会让覆盖工具满意,但真正的问题是它会让你的代码更好(更健壮,更少错误等)吗?

有一点是肯定的——这些测试既费时又无聊,而且可能给项目带来的价值较低。为了克服绝对需要编写这些测试的程序员的挫败感,甚至还有一些工具可以自动测试这些简单的 java bean(DTO 可以被视为一个 java bean),仅举几例:

https://github.com/codebox/javabean-tester

https://code.google.com/archive/p/junit-javabean-runner/

http://javabeantester.sourceforge.net/

现在完全不同的情况是,如果您测试某些服务或 DAO 的行为,例如生成 DTO - 这些测试无论是单元测试还是集成测试都是真正需要的。他们还将增加项目的覆盖面(甚至可能会覆盖 DTO 的代码,尽管这不是他们的主要目标),但我建议先开始编写这些测试。

【讨论】:

  • 所有这些为 DTO 创建单元测试只是出于好奇,因为我不知道它们是如何完成的,我想测试一下。在这种情况下,我为 DTO 使用了 JavaBeanTester,它运行良好并且比我目前拥有的更快,但是仍然需要覆盖覆盖级别,因为它获得了相同的百分比。 @Data 注释是黄色的,这可能是为什么?是否可以测试该注释?如果是这样,我该如何测试该注释?
  • 正如我所说,注释是龙目岛的,所以你不要测试。一般来说,您不应该测试不属于您的代码...
【解决方案2】:

我不知道最佳实践是什么,但 AFAIK 您应该从配置中排除 DTO 类,并且您不必为它们编写单元测试。

如果你使用 JaCoCo 插件,你最好看看这个:How to exclude certain classes from being included in the code coverage? (Java)

【讨论】:

  • 但我不想排除它们,我只想知道如何测试DTO类?
  • @sinfryd95 答案是:您的问题没有简单的答案。是什么让您认为 DTO 可以/应该像普通的其他类一样进行测试?
  • 好吧,从我所见,最好不要测试 DTO,而是从 pom 的测试中排除它们,对吧?现在我会尝试这样做
  • 我正在尝试使用 Jacoco 排除 DTO,我添加了以下 xml:<configuration> <excludes> <exclude> snmaddula / app / dto / ** / *. class </exclude> </excludes> </configuration>。然后我运行了mvn clean test,但它一直在做 DTO,我做错了什么?我必须在 xml 中更改什么?
猜你喜欢
  • 2020-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-08
  • 1970-01-01
  • 2013-09-30
  • 2019-01-05
  • 2011-03-16
相关资源
最近更新 更多