【发布时间】:2016-01-31 06:03:29
【问题描述】:
如何配置 Spring Boot、Spring Data JPA、Spring Test 和 Hibernate 以创建、使用和删除给定的 PostgreSQL 架构以用于保存和检索对象的单元测试?
在测试开始之前,Spring Test 应该为测试创建数据库模式。每个测试方法都应该在单个事务中运行,完成后,测试方法应该回滚所有数据库操作。在所有测试方法结束时,测试应该删除架构。
在其当前形式中,AccountRepositoryTest 通过,但在架构 public 中创建表 account,而不是在新架构 springboot 中创建表 account。
配置:
- Spring Boot 1.3.0.BUILD-SNAPSHOT
- Spring Data JPA 1.9.0.RELEASE
- 春季测试 4.2.3.BUILD-SNAPSHOT
- 休眠 4.3.11.Final
- PostgreSQL 9.5.4
AccountRepositoryTest.java
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(Application.class)
public class AccountRepositoryTest {
final static Logger logger = LoggerFactory.getLogger(AccountRepositoryTest.class);
@Autowired
AccountRepository accountRepository;
@Test
public void testSaveAccount() {
final Account newAccount = accountRepository.save(new Account("123", "Derek Mahar", 500.00));
final Account readAccount = accountRepository.findOne(newAccount.getId());
logger.info("New account UUID={}", newAccount.getId());
assertEquals(newAccount.getBalance(), readAccount.getBalance(), 0.001);
assertEquals(newAccount.getNumber(), readAccount.getNumber());
assertEquals(newAccount.getOwner(), readAccount.getOwner());
}
@Test
public void testFindByNumber() {
final Account newAccount = accountRepository.save(new Account("456", "Steve Balmer", 500.00));
final Account readAccount = accountRepository.findByNumber(newAccount.getNumber());
logger.info("New account UUID={}", newAccount.getId());
assertEquals(newAccount.getBalance(), readAccount.getBalance(), 0.001);
assertEquals(newAccount.getNumber(), readAccount.getNumber());
assertEquals(newAccount.getOwner(), readAccount.getOwner());
}
@Test
public void testFindByOwner() {
final Account newAccount = accountRepository.save(new Account("789", "Bill Gates", 500.00));
final Account readAccount = accountRepository.findByNumber(newAccount.getNumber());
logger.info("New account UUID={}", newAccount.getId());
assertEquals(newAccount.getBalance(), readAccount.getBalance(), 0.001);
assertEquals(newAccount.getNumber(), readAccount.getNumber());
assertEquals(newAccount.getOwner(), readAccount.getOwner());
}
}
AccountRepository.java
public interface AccountRepository extends CrudRepository<Account, UUID> {
Account findByNumber(String number);
Account findByOwner(String owner);
}
Account.java
@Entity
public class Account implements Serializable {
@Column(nullable = false)
private double balance;
@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Column
private UUID id;
@Column(nullable = false)
private String number;
@Column(nullable = false)
private String owner;
public Account(String number, String owner, double balance) {
this.number = number;
this.owner = owner;
this.balance = balance;
}
public Account() {
}
public double getBalance() {
return balance;
}
public UUID getId() {
return id;
}
public String getNumber() {
return number;
}
public String getOwner() {
return owner;
}
}
application.properties
spring.datasource.url=jdbc:postgresql:springboot
spring.datasource.username=springboot
spring.datasource.password=springboot
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.schema=springboot
spring.datasource.initialize=true
spring.jpa.database=springboot
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true
【问题讨论】:
-
我了解到,将注解
@Transactional(参见 docs.spring.io/spring/docs/current/spring-framework-reference/…)应用于测试类会指示 Spring 在事务中运行每个测试方法并回滚测试执行的所有数据库操作。但是,我还没有确定如何配置 Spring 来创建一个单独的模式来包含测试创建的数据库工件。 -
将
CREATE SCHEMA springboot添加到schema.sql(请参阅docs.spring.io/spring-boot/docs/current/reference/html/…)创建了架构springboot,但在单元测试完成时并未删除架构。因此,测试在下次运行时失败,因为架构springboot仍然存在。测试完成后如何强制 Spring 删除模式? -
理想情况下,我希望将
CREATE SCHEMA包含在与测试相同的事务中,以便在测试结束时回滚期间丢弃整个架构。
标签: java hibernate postgresql spring-boot spring-data-jpa