使用SpringExtension的@ContextConfiguration不会检测到显式定义的@Bean

时间:2019-02-06 14:38:13

标签: spring unit-testing junit

我正在将JUnit5与SpringExtension一起使用。但是出于某种原因,第一个测试成功,而第二个测试失败

谁能告诉我为什么失败了?

package com.acme;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import static org.assertj.core.api.Assertions.assertThat;

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = ConfigurationTest.Config.class)
public class ConfigurationTest {
  @Test
  void explicitContextTest() {
    AnnotationConfigApplicationContext applicationContext =
        new AnnotationConfigApplicationContext(Config.class);
    assertThat(applicationContext.getBean(Skeleton.class)).isNotNull();
  }

  @Test
  void contextConfigInjectionTest(Skeleton skeleton) {
    assertThat(skeleton).isNotNull();
  }

  @Configuration
  static class Config {
    @Bean
    Skeleton skeleton() {
      return new SkeletonImpl();
    }
  }

  interface Skeleton {
  }

  static class SkeletonImpl implements Skeleton {
  }
}

PS:如果我在@ComponentScan类级别添加Config,则第二次测试也成功。问题更多的是为什么除非我要求它进行显式扫描,否则为什么spring test无法检测到显式定义的bean

1 个答案:

答案 0 :(得分:0)

好像我必须为弹簧扩展插入的测试参数指定@Autowired

我刚刚尝试过。可行

package com.acme;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import static org.assertj.core.api.Assertions.assertThat;

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = ConfigurationTest.Config.class)
public class ConfigurationTest {
  @Test
  void explicitContextTest() {
    AnnotationConfigApplicationContext applicationContext =
        new AnnotationConfigApplicationContext(Config.class);
    assertThat(applicationContext.getBean(Skeleton.class)).isNotNull();
  }

  @Test
  void contextConfigInjectionTest(@Autowired Skeleton skeleton) {
    assertThat(skeleton).isNotNull();
  }

  @Configuration
  static class Config {
    @Bean
    Skeleton skeleton() {
      return new SkeletonImpl();
    }
  }

  interface Skeleton {
  }

  static class SkeletonImpl implements Skeleton {
  }
}

根据Spring扩展实现,spring期望@Autowired / @Qualifier / @Value出现。只有这样,spring才能根据ApplicationContext解析测试参数。否则,它根本无法解决

参考: https://github.com/spring-projects/spring-framework/blob/0ad9349d84a725dc37499bcb0ed2aad0de770c73/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtension.java#L156-L163