内存数据库数据中的 Spring Boot 测试在测试之间不会持续存在

nao*_*oru 0 junit spring-boot

我正在尝试做一个测试套件来检查我拥有的 @oneToMany 关系

我有一个 book_category 和一本书,但我的问题是我在测试类中有几个小测试,似乎每次测试后都会删除数据库(H2)

这是我的代码

@Slf4j
@RunWith(SpringRunner.class)
@DataJpaTest
@TestPropertySource(locations="classpath:test.properties")
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public class BookServiceTest {

    @Autowired
    private BookService bookService;

    @Autowired
    private BookCategoryService categoryService;

    @Test
    @Order(1) 
    public void insertBookCategories() {
        BookCategory cat1 = new BookCategory();
        cat1.setCategoryCode(32);
        cat1.setCategoryName("Category 1");
        BookCategory cat2 = new BookCategory();
        cat2.setCategoryCode(323);
        cat2.setCategoryName("Category 2");
        categoryService.save(cat1);
        categoryService.save(cat2);
        List<BookCategory> categories = categoryService.findAll();
        assertEquals(2, categories.size());
        log.debug("Executed test number 1");
    }

    @Test
    @Order(2) 
    public void createBookWithCategory() {
        Book book = new Book();
        book.setDescription("Test Book");
        book.setNumberOfSales(5);
        book.setTitle("Test title");
        BookCategory cat = categoryService.findByCategoryName("Category 2");
        assertNotNull(cat); <------- this fails!!!!
        assertEquals("Category 2", cat.getCategoryName());
        book.setCategory(cat);
        bookService.save(book);
        log.debug("Executed test number 2");
    }

    @Test
    @Order(3)
    public void deleteCategoryWithBook() {
        BookCategory cat = categoryService.findByCategoryName("Category 2");
        assertEquals("Category 2", cat.getCategoryName());
        categoryService.delete(cat);
        log.debug("Executed test number 3");

    }

    @Test
    @Order(4)
    public void assertBookIsNotNull() {
        Book book = bookService.findByTitle("Test title");
        assertEquals("Test Book", book.getDescription());
        assertNull(book.getCategory());
        log.debug("Executed test number 4");

    }
Run Code Online (Sandbox Code Playgroud)

当测试号 2 (createBookWithCategory) 中的代码尝试获取先前在测试 1 中插入的类别时,我得到一个空指针

我认为添加 @Transactional 注释将有助于保留数据,直到整个测试套件结束,但它不起作用

这是我的测试属性

h2.datasource.url=jdbc:h2:mem:somedatebase;DB_CLOSE_DELAY=-1
h2.datasource.username=sa
h2.datasource.password=
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.hbm2ddl.auto=create
Run Code Online (Sandbox Code Playgroud)

And*_*son 5

正如您所观察到的那样,用 are 注释的测试@DataJpaTest已经@Transactional如此显式添加@Transactional将不起作用。

您看到的行为是因为默认情况下,测试框架会在每次测试结束时回滚事务。这是为了避免一个测试中对数据库所做的更改影响另一测试的行为。通常建议这样做,因为它允许您的测试以任何顺序执行。

在您的情况下,您已经订购了测试,并且希望在一个测试中所做的更改会影响后续测试。您可以通过使用 注释方法来指示测试框架提交测试方法的事务@Commit。或者,如果您希望类中的每个测试都提交其事务,您可以使用注释该类@Commit

@Commit您可以在事务回滚和提交行为@Rollback的参考文档中了解更多相关信息。