programing

스프링 부트: 연동 테스트 중 @TestConfiguration이 Bean을 덮어쓰지 않음

lastcode 2023. 2. 13. 20:32
반응형

스프링 부트: 연동 테스트 중 @TestConfiguration이 Bean을 덮어쓰지 않음

는 나나 a a a가 있다Beandefined defined with with로 @Configuration:

@Configuration
public class MyBeanConfig {
    @Bean
    public String configPath() {
        return "../production/environment/path";
    }
}

나는 다음 장식으로 수업이 있다.@TestConfiguration하는 것이 좋을 것 같습니다.Bean:

@TestConfiguration
public class MyTestConfiguration {
    @Bean
    @Primary
    public String configPath() {
        return "/test/environment/path";
    }
}

configPathbean은 시작 시 읽어야 하는 등록 코드를 포함하는 외부 파일의 경로를 설정하기 위해 사용됩니다.은 '하다'에 쓰입니다.@Component 링크:

@Component
public class MyParsingComponent {
    private String CONFIG_PATH;
    
    @Autowired
    public void setCONFIG_PATH(String configPath) {
        this.CONFIG_PATH = configPath;
    }
}

디버깅을 시도하면서 각 메서드 내부와 테스트 설정 클래스의 컨스트럭터를 설정합니다.@TestConfiguration의 컨스트럭터 하고 있기 인스턴스화되는 은 알고 「」는 「」입니다.configPath그 클래스의 메서드는 히트하지 않습니다. configPath@Configuration하여 " " "가"가 됩니다.@Autowired StringMyParsingComponent 있다../production/environment/path했던 것보다/test/environment/path.

왜 이런 일이 일어나는지 모르겠다.어떤 의견이라도 주시면 감사하겠습니다.

Spring Boot 레퍼런스 매뉴얼의 "Detecting Test Configuration" 섹션에서 설명한 바와 같이 최상위 클래스에서 설정된 모든 콩에는 다음과 같은 주석이 붙어 있습니다.@TestConfiguration컴포넌트 스캔을 통해 픽업되지 않습니다.따라서 명시적으로 등록해야 합니다.@TestConfiguration를 누릅니다

할 수 요.@Import(MyTestConfiguration.class) ★★★★★★★★★★★★★★★★★」@ContextConfiguration(classes = MyTestConfiguration.class)네 시험 수업에서.

만약 에 편, 신, 신, 신, 신, 신, 면, 면, 면, 면, 면, 면, 면, 면, 면, 면, on, on, on, on, with, with, with, with@TestConfiguration werestatic테스트 클래스에 중첩된 클래스가 자동으로 등록됩니다.

@Bean 팩토리 메서드의 메서드 이름이 기존 콩 이름과 일치하지 않는지 확인하십시오.config()나 (내 경우) prometheusConfig()와 같은 메서드 이름에 문제가 있었습니다.봄은 그 공장 방법들을 묵묵히 건너뛰고 단순히 그것을 부르지 않거나 콩을 인스턴스화하지 않는다.

테스트에서 빈 정의를 덮어쓰려면 @Bean("beanName") 주석에서 빈 이름을 문자열 매개 변수로 명시적으로 사용하십시오.

  • 은 Import를 통해 .@Import({MyTestConfiguration.class}).
  • @Bean@Configuration ★★★★★★★★★★★★★★★★★」@TestConfiguration달라야 합니다.스프링 부트 v22년 전하다
  • ㅇ, ㅇ, ㅇ, ㅇ, ㅇ, ㅇ, ㅇ, ㅇ, ㅇ, ㅇ, ㅇ, ㅇspring.main.allow-bean-definition-overriding=true이치노릇을 하다

나는 이 코드를 조작했다.

  @TestConfiguration // 1. necessary
  public class TestMessagesConfig {

    @Bean
    @Primary // 2. necessary
    public MessageSource testMessageSource() { // 3. different method name than in production code e.g. add test prefix

    }
  }

이너 스태틱 클래스를 사용했는데도 테스트빈이 등록되지 않는 문제가 있었습니다.

클래스는 '스태틱 클래스'에 @ContextConfigurationarray. 내의 @TestConfiguration @TestConfiguration test내내test 。

public interface Foo {
    String execute();
}
public class FooService {
    private final Foo foo;

    FooService(Foo foo) {
        this.foo = foo;
    }

    public String execute() {
        return foo.execute();
    }
}
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {FooService.class, FooTest.FooTestConfig.class})
public class FooTest {
    @Autowired
    FooService fooService;

    @Test
    void test() {
        Assertions.assertEquals("MY_TEST_BEAN", fooService.execute());
    }

    @TestConfiguration
    static class FooTestConfig {
        @Bean
        public Foo getFooBean() {
            return () -> "MY_TEST_BEAN";
        }
    }
}

최근에 비슷한 문제가 발생하여 테스트 빈에 @Primary와 @Bean을 주석을 달아 해결했습니다.왜 필요한지는 모르겠지만 스프링 문서에는 기재되어 있지 않은 것 같습니다.Spring Boot 버전은 2.0.3입니다.

에는 ★★★★★★★★★★★★★★★★★★★★★★★★★★의 문제였습니다.@RunWith(SpringRunner.class)동작하지 않는 이유를 정확히 알 수 없습니다.이것에 따르고 있었습니다-스프링 부트에서의 테스트

을 지지 that that 로 대체한 후@ExtendWith(SpringExtension.class) 정전기@TestConfiguration이치노

버전이 일치하지 않을 수 있습니다.Spring Boot 2.7.2를 사용하고 있습니다.

제 경우는 @를 교환해 주세요.Import(TestConfig.class)@ContextConfiguration(classes=TestConfig.class)인지 은 TestConfig의 콩이지만TestConfig의 콩은 제가 TestConfig의 콩을 대체할 때까지 없었습니다.@Import@ContextConfiguration이것은, 업 투표가 없었기 때문에 숨겨져 있던 코멘트에서도 언급되고 있습니다.

에서 그 하다는 되었다.@Bean는 서로 달라야 합니다.어떻게 한 쪽이 다른 쪽보다 우선시 되는 거죠?
저에게 맞는 답변은 하나도 없었지만, 저는 그들의 조언을 몇 가지 조합하여 문제를 해결했습니다.

나한테 효과가 있었던 건 이거야

주 구성 클래스:

@Configuration
public class SpringConfiguration {

    @Bean
    BeanInterface myBean() {
        return new BeanImplementation();
    }
    
    @Bean
    OtherClass otherBean() {
        return new OtherClass();
    }
}

테스트 구성 클래스:

@TestConfiguration
public class TestSpringConfiguration {

    @Bean
    @Primary
    BeanInterface myBean() {
        return new TestBeanImplementation();
    }
}

테스트 클래스:

@SpringBootTest(classes = TestSpringConfiguration.class, 
        properties = "spring.main.allow-bean-definition-overriding=true")
public class Tests {
    
    @Test
    public void test() {
        // do stuff
    }
}

콩 인스턴스는 "myBean" .TestSpringConfiguration 반면 'otherBean'은 'otherBean'입니다).SpringConfiguration수업
2개의 "은 아직 중에 할 수 있는입니다. "myBean"은 "MyBean"을 "MyBean"을 "MyBean"으로 지정합니다.
내가 같은 이름을 붙이면 스프링은 서로 상충한다고 오류를 던지곤 했다. 나는 그 .spring.main.allow-bean-definition-overriding=true @SpringBootTest테스트 클래스의 주석.



덧붙여서, Spring Boot를 사용하지 않는 경우는, 다음의 대체 주석을 사용할 수 있습니다.

@ExtendWith(value = SpringExtension.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class, // <- not sure about this one
        classes = { SpringConfiguration.class, TestSpringConfiguration.class })
public class Tests {
    
    @Test
    public void test() {
        // do stuff
    }
}

다음에 '을 '성질'로 돼요.spring.main.allow-bean-definition-overriding=trueapplication.yml ★★★★★★★★★★★★★★★★★」application.properties파일 또는 부팅 시 코드를 통해 다른 방법으로 파일을 만듭니다.

주의: 고객님께 필요한 것은 100% 확실치 않습니다.loader = AnnotationConfigContextLoader.class거그없 、 ,저저,, 。Spring without Boot 프로젝트에서는 필요했는데, 표준 설정인지, 어떤 이유로 필요했는지 기억이 나지 않습니다.

언급URL : https://stackoverflow.com/questions/50607285/spring-boot-testconfiguration-not-overriding-bean-during-integration-test

반응형