>

Spring 5, Junit4.11 및 JDK8을 사용하여 일부 통합 테스트를 실행하기 전에 @SqlGroup으로 일부 SQL 문을 실행하려고합니다.

주석이 @PostConstruct 인 "ConfigurationComponent"Bean에 초기 구성을 추가 할 때까지 오늘까지 모든 것이 완벽하게 작동했습니다.

@PostConstruct 메소드는 데이터베이스 종속 Bean을 호출하므로 최대 절전 모드 (따라서 데이터베이스)가 사전로드 된 스키마를 찾을 수 없으므로 테스트에 실패합니다.

조사한 결과 @SqlGroup에 입력 한 명령문이 ApplicationContext 초기화 후에 실행되므로 스키마가로드되기 전에 @PostConstruct가 실행된다는 것을 발견했습니다.

다음은 통합 테스트 추상 클래스입니다.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:application-context-test.xml" })
@Transactional
@Rollback(true)
@SqlGroup({
        @Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD, scripts = {
                "classpath:db_config.sql",
                "classpath:consultas/setup_esquema_0.1.sql",
                "classpath:db_datos_iniciales.sql"}),
        @Sql(executionPhase = ExecutionPhase.AFTER_TEST_METHOD, scripts = "classpath:db_teardown.sql") })
public abstract class AbstractServiceTest {
    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
    }
    @AfterClass
    public static void tearDownAfterClass() throws Exception {
    }
    @Before
    public abstract void setUp() throws Exception;
    @After
    public abstract void tearDown() throws Exception;
    public static Long randomId() {
        return new Long(Math.round(Math.random() * 1000));
    }
}

불쾌한 콩

@Configuration
public class ConfigurationComponent {
    @Autowired
    Resources resources; // resources are retrieved from database.
    @PostConstruct
    public void startUp() throws VariableGlobalInexistenteException {
        Config.environment = resources
                .getWsaaEnv();
        Config.validation = resources
                .getWsaaEnvValidation();
    }
}

@SqlGroup을 사용하여이 문제를 극복 할 수있는 방법을 찾을 수 없습니다. 라이프 사이클을 변경하고 SQL 문을 먼저 실행하는 방법이 있습니까? 보시다시피 ExecutionPhase.BEFORE_TEST_METHOD 를 사용하고 있습니다. , 없습니다 이 경우 "ExecutionPhase.BEFORE_SETUP"과 같은 명시 적 구성.

<시간>

업데이트 [email protected]을 사용하여이를 달성 할 방법이없는 것 같습니다 :

Both @Sql and the calling of @PostConstruct are handled by Spring Framework rather than Spring Boot. Also, I believe this is working as designed. The default execution phase for @Sql is BEFORE_TEST_METHOD (the other option is AFTER_TEST_METHOD). The application context is refreshed, and therefore @PostConstruct is called, once for the whole test class (in fact it could be once for multiple test classes if they share the same configuration) which happens before individual test methods are called. In other words, you cannot use @Sql as a means of preparing the database for calls that are made in @PostConstruct.

@Sql 이전에 실행 된 Github @PostConstruct

  • 답변 # 1

    해결책을 찾았습니다. 최신 업데이트에서 언급했듯이 @SqlGroup을 사용하여 원하는 동작을 수행 할 수있는 방법이 없습니다. @BeforeClass와 @AfterClass를 사용하여 다음 접근법을 사용해야했습니다.

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        DriverManagerDataSource dataSource = getDataSource();
        Connection conn = dataSource.getConnection();
        ScriptUtils.executeSqlScript(conn, new ClassPathResource("db_config.sql"));
        ScriptUtils.executeSqlScript(conn, new ClassPathResource("consultas/setup_schema"));
        ScriptUtils.executeSqlScript(conn, new ClassPathResource("db_init.sql"));
        JdbcUtils.closeConnection(conn);
    }
    @AfterClass
    public static void tearDownAfterClass() throws Exception {
        Connection conn = getDataSource().getConnection();
        ScriptUtils.executeSqlScript(conn, new ClassPathResource(
                "db_teardown.sql"));
        JdbcUtils.closeConnection(conn);
    }
    private static DriverManagerDataSource getDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setDriverClassName(driver);
        return dataSource;
    }
    
    

    모든 @SqlGroup 주석이 제거되었습니다. ScriptUtils를 실행하는 데 많은 종속성이 필요하지 않기 때문에이 방법은 매우 깨끗합니다.

  • 답변 # 2

    또 다른 해결 방법은 CommandLineRunner를 구현하는 것입니다.

    @Component
    public class ConfigurationInitRunner implements CommandLineRunner {
        @Autowired
        Resources resources; // resources are retrieved from database.
        @Override
        public void run(String... strings) throws Exception {
            Config.environment = resources.getWsaaEnv();
            Config.validation = resources.getWsaaEnvValidation();
        }
    }
    
    

  • 이전 Emacs에서 현재 선을 어떻게 삭제할 수 있습니까?
  • 다음 npm - 게시 된 각도 라이브러리는 npmjs에서 모듈을 가져 오지 않았습니다