@DataJpaTest ignores @Column(unique = true) and @Column(null



我在测试Jpa的保存操作时有一个问题。

我有一个User对象:

@Entity
@Table(name = "USERS", schema = "ecommercy")
@EntityListeners(AuditingEntityListener.class)
@JsonIgnoreProperties(value = {"createdAt", "updatedAt"}, allowGetters = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@ToString
public class User {
@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
@Column(updatable = false, nullable = false, columnDefinition = "VARCHAR(255)")
private String id;
@Column(unique = true, nullable = false)
private String email;
@Column(unique = true)
private String phoneNumber;
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
@Column(nullable = false)
private String password;
@Column(nullable = false)
private String name;
private String lastName;
@OneToMany(mappedBy = "user")
@Cascade(org.hibernate.annotations.CascadeType.ALL)
private List<Address> addresses;
@OneToOne(mappedBy = "user")
@Cascade(org.hibernate.annotations.CascadeType.ALL)
private Basket basket;
@OneToMany(mappedBy = "user")
@Cascade(org.hibernate.annotations.CascadeType.ALL)
private List<Order> orders;
@Builder.Default
@Column(nullable = false)
private int points = 0;
@OneToMany(mappedBy = "user")
@Cascade(org.hibernate.annotations.CascadeType.ALL)
private List<Comment> comments;
@Builder.Default
@Convert(converter = StringListConverter.class)
@Column(updatable = false)
private List<String> roles = List.of("USER");
@Builder.Default
@Temporal(TemporalType.TIMESTAMP)
@CreatedDate
@Column(nullable = false, updatable = false)
private Date createdAt = new Date();
@Builder.Default
@Column(nullable = false)
@Temporal(TemporalType.TIMESTAMP)
@LastModifiedDate
private Date updatedAt = new Date();
}

您可以看到一些用户字段,如姓名或电子邮件有@Column(unique = true)或@Column(nullable = false)

当我运行应用程序时,一切正常,工作完美。

但是当我尝试用Junit5测试这两个注释时,什么也不会发生,也不会抛出异常,测试将成功通过。

@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class UserRepositoryTests {
@Autowired
private UserRepository userRepository;
@Test
void ifEmailIsNullMustThrowException() {
// Arrange
User user = User.builder()//
.name("John")//
.lastName("Doe")//
.password("password")//
.phoneNumber("123456789")//
.build();
// Act
User savedUser = userRepository.save(user);
// Assert
assertNull(savedUser);
}
@Test
void ifAUserExistWithGivenEmailMustThrowException() {
// Arrange
User user1 = User.builder()//
.name("John")//
.lastName("Doe")//
.email("johndoe@email.com")//
.password("password")//
.phoneNumber("123456789")//
.build();
User user2 = User.builder()//
.name("John")//
.lastName("Doe")//
.email("johndoe@email.com")//
.password("password")//
.phoneNumber("123456789")//
.build();
userRepository.save(user1);
// Act
User savedUser = userRepository.save(user2);
// Assert
assertNull(savedUser);
}
}

@DataJpaTest使您的测试@Transactional,这意味着测试中的所有内容都在事务中运行,并在测试后回滚。这与AUTO的默认刷新模式(在提交时自动刷新)相结合,使得在测试中不会对数据库产生实际的SQL问题。(启用查询日志记录将显示这一点)。如果没有对数据库的SQL,则不会触发任何约束,因此不会出现异常。

你可以做两件事。

  1. 使用saveAndFlush而不是save,因为这将刷新数据库的更改,从而发出SQL。
  2. 注入TestEntityManager,在所有调用之后,在断言之前,调用flush方法,以便同步数据库的更改并发出SQL。

都可以,因为它将触发刷新更改。

最新更新