source

JUnit 테스트 중 응용 프로그램/CommandLineRunner 클래스 실행 방지

manysource 2023. 3. 6. 21:17

JUnit 테스트 중 응용 프로그램/CommandLineRunner 클래스 실행 방지

TestCase 클래스에 다음과 같은 주석이 있는 경우:

@SpringApplicationConfiguration(classes = {Application.class})

이로 인해Application.class, 의 실장CommandLineRunner인터페이스, 필요한 메서드를 실행합니다.

public void run(String... args) throws Exception

테스트 환경에서는 어플리케이션 전체를 기동하고 싶지 않을 수 있기 때문에, 이 동작은 대부분 바람직하지 않은 동작이라고 생각합니다.

이 문제를 회피하기 위한 두 가지 솔루션이 있습니다.

  1. 제거하다CommandLineRunner내 인터페이스Application학급
  2. 테스트의 맥락이 다르다

두 솔루션 모두 많은 코딩이 필요합니다.좀 더 편리한 해결책이 있나요?

Jan의 해결책은 더 쉽게 달성될 수 있다.

테스트 클래스에서 "테스트" 프로파일을 활성화합니다.

@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("test")
public class MyFancyTest {}

CommandLineRunner에서 프로파일을 NOT test로 설정합니다.

@Component
@Profile("!test")
public class JobCommandLineRunner implements CommandLineRunner {}

그러면 응용프로그램에서 프로파일을 수동으로 설정할 필요가 없습니다.

스프링 매뉴얼에서 설명한 바와 같이 @Context Configuration은 특수 이니셜라이저와 함께 사용할 수 있습니다.

ConfigDataApplicationContextInitializer는 입니다.ApplicationContextInitializer스프링 부트를 로드하기 위해 테스트에 적용할 수 있습니다.application.properties모든 기능이 필요하지 않을 때 사용할 수 있습니다.@SpringBootTest

이 예에서는anyComponent초기화되고 속성이 주입되지만run(args)메서드는 실행되지 않습니다.(Application.class봄의 주요 시작점)

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Application.class, 
                      initializers = ConfigDataApplicationContextInitializer.class)
public class ExtractorTest {
    @Autowired
    AnyComponent anyComponent;
    
    @Test
    public void testAnyComponent() {
       anyComponent.anyMethod(anyArgument);
    }
}

CommandLineRunner 를 실장하고 있는 콩을 제외하고, 애플리케이션과 같은 패키지로 테스트 설정을 정의할 수 있습니다.여기서의 키는 @ComponentScan.excludeFilters 입니다.

@Configuration
@ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = CommandLineRunner.class))
@EnableAutoConfiguration
public class TestApplicationConfiguration {
}

다음으로 테스트 설정을 치환하기만 하면 됩니다.

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = TestApplicationConfiguration.class)
public class SomeApplicationTest {
    ...
}

CommandLineRunner는 설정의 일부가 아니기 때문에 현재 실행되지 않습니다.

파티에 좀 늦었지만, 합리적인 접근법은 이 콩을 로 장식하는 것이다.@ConditionalOnProperty,예.

@ConditionalOnProperty(prefix = "job.autorun", name = "enabled", havingValue = "true", matchIfMissing = true)
public CommandLineRunner myRunner() {...}

그런 다음 다음 주석에 따라 테스트에서 해당 주석은 비활성화됩니다.

@SpringBootTest(properties = {"job.autorun.enabled=false"})

모의 프레임워크(예: MockMVC)가 설치되어 있는 경우 CommandLineRunner 구현의 모의 인스턴스를 생성하여 다소 비활성화할 수 있습니다.

@MockBean 프라이빗 TextProcessor myProcessor;

이전의 답변들은 나에게 효과가 없었다.다른 프로파일을 사용하게 되었습니다.Spring Boot의 init 메서드의 예:

SpringApplication app = new SpringApplication(AppConfig.class);
app.setAdditionalProfiles("production");
app.run(args);

테스트 중에는 실행되지 않기 때문에 여기서는 안전합니다.

모든 테스트에는 자체 프로파일 "test"가 있습니다(다른 여러 가지 측면에서도 유용함).

@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("test")
public class MyFancyTest {}

명령줄 러너에는 "실가동" 프로파일이 주석을 달기 때문에 테스트에서는 이를 무시합니다.

@Component
@Profile("production")
public class JobCommandLineRunner implements CommandLineRunner {}

Command Line Runner를 구현하지 않음으로써 이 문제를 해결합니다.콘텍스트에서 빈을 가져와 메서드를 호출하면 argv를 통과합니다.이렇게 하면 동일한 결과를 얻을 수 있으며 테스트 실행 시 응용 프로그램이 자동으로 시작되지 않습니다.

언급URL : https://stackoverflow.com/questions/29344313/prevent-application-commandlinerunner-classes-from-executing-during-junit-test