【发布时间】:2019-12-31 13:59:17
【问题描述】:
我的 Spring Boot 集成测试中有以下 @Before 和 @After:
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac)
.addFilter(springSecurityFilterChain).build();
user = userRepository.save(
new User("Joe", "Bloggs", "joe@example.com", "joe", passwordEncoder.encode("secret")));
currency = currencyRepository.save(
new Currency("GBP", "£%01.2f"));
fund = fundRepository.save(
new Fund("Nationwide", (double) 100, currency));
}
@After
public void teardown() {
userRepository.delete(user);
currencyRepository.delete(currency);
fundRepository.delete(fund);
}
但是,每次测试后似乎都没有删除货币,而且我的测试错误地失败了:
...
[ERROR] testGetFunds_whenNoToken_thenUnauthorized(biz.martyn.budget.FundsControllerTest) Time elapsed: 3.268 s <<< ERROR!
org.springframework.orm.jpa.JpaObjectRetrievalFailureException: Unable to find biz.martyn.budget.currency.Currency with id 437; nested exception is javax.persistence.EntityNotFoundException: Unable to find biz.martyn.budget.currency.Currency with id 437
Caused by: javax.persistence.EntityNotFoundException: Unable to find biz.martyn.budget.currency.Currency with id 437
...
之后,如果我查询测试数据库,我看到行没有被删除:
mysql> select * from currencies;
+----+---------------------+---------------------+---------------+------+---------------------+
| id | created_at | deleted_at | format | name | updated_at |
+----+---------------------+---------------------+---------------+------+---------------------+
...
| 437 | 2020-01-02 13:51:24 | 2020-01-02 13:51:23 | £%01.2f | GBP | 2020-01-02 13:51:24 |
...
+----+---------------------+---------------------+---------------+------+---------------------+
5 rows in set (0.00 sec)
名称应该只有一个唯一条目,但我猜由于删除没有发生,它正在为“GBP”提取重复项。我的货币存储库:
Currency.java
@Entity(name = "currencies")
@SQLDelete(sql = "UPDATE currencies SET deleted_at = now() WHERE id = ?")
@Where(clause = "deleted_at is null")
public class Currency {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected Integer id;
@Column(unique = true, nullable = false)
private String name;
@Column(nullable = false)
private String format;
@Column(name = "created_at", updatable = false)
@CreationTimestamp
protected LocalDateTime createdAt;
@Column(name = "updated_at")
@UpdateTimestamp
protected LocalDateTime updatedAt;
@Column(name = "deleted_at")
protected LocalDateTime deletedAt;
protected Currency() {}
public Currency(String name, String format) {
this.name = name;
this.format = format;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
public String getFormat() {
return format;
}
public void setFormat(final String format) {
this.format = format;
}
}
用户.java
@Entity(name = "users")
public class User implements Serializable {
/**
*
*/
private static final long serialVersionUID = -8507204786382662588L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable = false)
private String firstName;
@Column(nullable = false)
private String surname;
@Column(nullable = false, unique = true)
private String email;
@Column(nullable = false, unique = true)
private String username;
@Column(nullable = false)
@JsonIgnore
private String password;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name="user_id")
@JsonIgnore
private List<Fund> funds;
protected User() {}
public User(String firstName, String surname, String email, String username, String password) {
this.firstName = firstName;
this.surname = surname;
this.email = email;
this.username = username;
this.password = password;
}
public Long getId() {
return id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
// standard getters and setters
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public List<Fund> getFunds() {
return funds;
}
public void addFund(Fund fund) {
funds.add(fund);
fund.setUser(this);
}
public void removeFund(Fund fund) {
funds.remove(fund);
fund.setUser(null);
}
// public Fund getFund(int id) {
// fundRepository.findByIdAndUserId(id)
// .orElseThrow(() -> new EntityNotFoundException("Fund ID not found: "+id));
// }
}
【问题讨论】:
-
是 SpringBootTest 还是 DataJpaTest?
-
索引 UK_abaar0d2ymp2spkrkjnekr1h8 是如何定义的?
-
这是 SpringBootTest。我不知道 UK_... 字符串是在哪里定义的,我的列或属性都没有这样命名。
-
用
@Transactional注释你处理数据库操作的测试类,你应该准备好了;否则尝试使用@DataJpaTest。 -
货币实体或任何其他实体属性中是否有任何属性声明为唯一?
标签: spring-boot spring-data-jpa spring-boot-test