用于测试的全局模拟对象?

Global mock objects for tests?

我正在创建 Spring Boot Web 应用程序,我正在使用 JUnit 5 进行单元测试。

我对单元测试有一个顾虑。在一个 class 中使一些模拟对象成为全局对象是一种很好的做法,当我们在不同的测试中需要它们时 return 它们具有功能 classes?

我问这个是因为我最近在我的模型中添加了一个新字段 class,并且需要修改一堆测试 classes 并在每个测试中将此字段添加到构造函数 class.

让我们以三个 classes 学期、模块和课程为例,其中课程有学期和模块作为字段:

@AllArgsConstructor
public class Module{
  private Long id;
  private String name;
}


@AllArgsConstructor
public class Semester{
  private Long id;
  private LocalDate startingDate;
}

@AllArgsConstructor
public class Course {
  private Long id;
  private String name;
  private Module module;
  private Semester semester;
}

现在,在我们需要某种课程对象的所有测试 class 中,我们需要创建所有这些对象,如下所示:

private final Module mockModule = Module(1L, "Computer Sciences");
private final Semester mockSemester = Semester(1L, LocalDate.of(2021, Month.MARCH, 1));
private final Course mockCourse = Course(1L, "DSA", mockModule, mockSemester); 

一段时间后,我们发现模块 class 中还需要一个字段,例如 codeName:

@AllArgsConstructor
public class Module{
  private Long id;
  private String name;
  private String codeName;
}

这一字段更改后,我们将需要编辑我们使用模块构造函数的所有测试 classes。如果我们想在学期 class.

中添加新字段,情况也是如此

但是在我们将所有模拟对象都放在一个 class 中的情况下,我们将只需要在这个 class 中编辑构造函数,而不是在所有测试 class 中。测试 class 中的代码将是:

private final Course mockCourse = mockObjects.getMockCourse();

有没有更“干净”的方法来做到这一点?

我试图找到这个问题的答案,但是在关于单元测试的所有 tutorials/articles 中,我发现每个测试 class 都有自己的模拟对象。

您可以在此处应用 Object Mother 模式并创建一个全局工厂 class 来构造用于多个测试的对象以减少样板代码。如果您的对象结构发生变化,您只需触摸一个文件(最好)。

Tom Hombergs 写了一篇很棒的文章,他展示了 Object Mother in combination with the builder pattern

最后,您将得到如下内容:

CourseMother.completedCourse();
CourseMother.emptyCourse();
// etc.