两种识别同一实体的方法,以便于测试

时间:2018-06-02 23:05:54

标签: java spring spring-mvc spring-boot testing

我有一个班级,例如

@Setter
@EqualsAndHashCode(of = "id")
@Entity
public class MovieBoxOfficeEntity {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Setter(AccessLevel.NONE)
        private Long id;
}

具有自动生成的ID而无需手动设置。我也有一个方法

@Entity
@Table(name = "movies")
public class MovieEntity {

       List<MovieBoxOffice> boxOffices = new ArrayList<>();

       public void addBoxOffice(MovieBoxOffice boxOffice) throws ResourceConflictException {
            if (this.boxOffices.contains(boxOffice)) {
                 throw new ResourceConflictException("A box office with id " + boxOffice.getId() + " is already added");
            }
           this.boxOffices.add(boxOffice);
      }
}

测试方法addBoxOffice时出现问题,因为MovieBoxOfficeEntity对象的比较是使用ID完成的,ID仅在编写时自动生成到数据库,不能手动设置。

我想到了将uniqueId字段添加到MovieBoxOfficeEntity类并将其添加到@EqualsAndHashCode注释

的想法
@Setter
@EqualsAndHashCode(of = {"id", "uniqueId"})
@Entity
public class MovieBoxOfficeEntity {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Setter(AccessLevel.NONE)
        private Long id;

        private String uniqueId = UUID.randomUUID().toString();
}

然后我可以这样测试

@Test(expected = ResourceConflictException.class)
public void canAddBoxOffice() throws ResourceConflictException{
    final String id = UUID.randomUUID().toString();
    final MovieBoxOfficeEntity boxOffice = new MovieBoxOfficeEntity();
    boxOffice.setUniqueId(id);

    this.movieEntity.addBoxOffice(boxOffice);
    this.movieEntity.addBoxOffice(boxOffice);
}

以这种方式,对象boxOffice将具有

id: null
uniqueId: some generated UUID

并且对象的比较将在uniqueId比较中进行。

您如何考虑创建uniqueId字段来测试实体方法?

1 个答案:

答案 0 :(得分:0)

添加 uniqueId 可能会导致冲突。假设有两个发现者。创建结果后,将为数据库中的相同行创建两个实例。它们具有相同的 id ,但不同的 uniqueId 。意味着,两个对象具有相同的主键,但等于返回 false 。这可能导致应用程序逻辑和JPA实现中的错误。

您可以覆盖等于。但是使用与表相关的实体属性,而不是随机生成的UUID。