首页 > 解决方案 > 无法通过 @Sql 注释自动运行 sql 脚本

问题描述

我绝对需要使用带有注释@BeforeAll@AfterAll的非静态方法。但是这些注解只有在我们有

@TestInstance(TestInstance.Lifecycle.PER_CLASS)

@ActiveProfiles("test")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public abstract class ApplicationTests extends ContainerConfig{

    @Autowired
    protected TestRestTemplate testRestTemplate;

    @Autowired
    protected BasicUserRepository basicUserRepository;
    
}

/**
* If you prefer JUnit Jupiter
* performed all testing methods in a single test instance,
* annotate your test class with @testInstance(Lifecycle.PER_CLASS) .
* When using this mode, a new test instance is created
* will be created once for each test class, that is, all nodes of the test class
* of a tree (that is, of this class) they will use the same object, that is,
* an object of this class, and methods, will be called on this object and use the state,
* which this object has.
* Therefore, be careful if your test nodes will change the properties of this
* an object during the processing of its tests.
* In this case, you can use the @BeforeAll and @AfterAll annotations over non-static
* methods
*/
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@Sql(scripts = "/sql/sql-data.sql")
class UserControllerTest extends ApplicationTests  {

    private String NAME_USER;

    @BeforeAll
    void setUp() {

        List<BasicUser> userList = super.basicUserRepository.findAll();
        NAME_USER = userList
                .stream()
                .map(BasicUser::getUsername)
                .findFirst()
                .orElse("");

        if (NAME_USER.isEmpty()) {
            throw new RuntimeException("Not Found users.");
        }
    }

    @Test
    void findOne() {

        String uri = "/users/{username}";

        DetailedUserDto userDto =
                super.testRestTemplate
                        .getForObject(uri,
                                DetailedUserDto.class,
                                NAME_USER);

        Long id = userDto.getId();
        String name = userDto.getUsername();
        Set<String> permissions = userDto.getPermissions();
        int sizeEmptyCollection = 0;
        assertTrue(permissions.size() > sizeEmptyCollection);

        int emptyId = 0;
        assertTrue(id > emptyId);
    }

    @AfterAll
    void clearDb() {
        basicUserRepository.deleteAll();
    }
}

但是当使用@TestInstance(testInstance.Lifecycle.PER_CLASS)时,sql 脚本的自动运行不起作用,通过注释@Sql

为什么会发生,我该如何纠正?

标签: postgresqlspring-bootjunit5java-11testcontainers-junit5

解决方案


@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class UserControllerTest extends ApplicationTests {

    private boolean isInitDatabase = false;

    private String NAME_USER;

    @BeforeEach
    void setUp() {

        if(isInitDatabase) return;

        isInitDatabase = true;

      .............

}
@ActiveProfiles("test")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Sql(scripts={"/sql/sql-data.sql"}, executionPhase = BEFORE_TEST_METHOD)
public abstract class ApplicationTests extends ContainerConfig{

    @Autowired
    protected TestRestTemplate testRestTemplate;

    @Autowired
    protected BasicUserRepository basicUserRepository;

}


推荐阅读