使用 @WebMvcTest 测试中的 ApplicationContext 异常

Posted

技术标签:

【中文标题】使用 @WebMvcTest 测试中的 ApplicationContext 异常【英文标题】:ApplicationContext Exception in Test with @WebMvcTest 【发布时间】:2018-08-03 11:35:53 【问题描述】:

我有一个 Spring Boot 应用程序 (1.5.10.RELEASE),其中包含一个主程序 (SpringBootApplication),如下所示:

@SpringBootApplication
@Configuration
@EntityScan(basePackages =  "db.modell", "db.modell.base" )
@ComponentScan(basePackages =  "de.gui.test" )
public class SpringBootConsoleApplication 
   public static void main(String[] args) throws Exception 
    SpringApplication.run(SpringBootConsoleApplication.class, args);
  

还有两个 REST 控制器,如下所示:

@RestController
@RequestMapping("/as")
public class AController 
  @Autowired
  private ARepository aRepository;

  @RequestMapping(method = RequestMethod.GET)
  public ResponseEntity<Collection<A>> getAs() 
    return new ResponseEntity<>(orgtFarbeRepository.findAll(), HttpStatus.OK);
  

  @RequestMapping(value = "/id", method = RequestMethod.GET)
  public ResponseEntity<A> getA(@PathVariable long id) 
    A a = ARepository.findOne(id);

    if (party != null) 
      return new ResponseEntity<>(ARepository.findOne(id), HttpStatus.OK);
     else 
      return new ResponseEntity<>(null, HttpStatus.NOT_FOUND);
    
  

此外,我有一个这样的测试:

@RunWith(SpringRunner.class)
@WebMvcTest(AController.class)
public class AControllerTest 

  @Autowired
  private MockMvc mvc;

  @MockBean
  private ARepository ARepository;

  @Test
  public void firstTest() throws Exception 
    A a = new aFarbe();
    a.set....
    when(ARepository.findAll()).thenReturn(Collections.singleton(a));
    mvc.perform(
            get("/as")
            .accept(MediaType.APPLICATION_JSON_UTF8_VALUE)
    )
      .andExpect(status().isOk());
  

存储库如下所示:

public interface ARepository extends CrudRepository<A, Long>

    Collection<A> findAll();

public interface BRepository extends CrudRepository<B, Long>

  Collection<B> findAll();

A 和 B 他们自己是 JPA 注释类。整个应用程序包含对数据库的访问..

此外,我有这样的服务:

@Service
public class XService 
  private static final Logger LOGGER = LoggerFactory.getLogger(XService.class);

  @Autowired
  private ARepository aRepository;

  @Autowired
  private BRepository bRepository;
...

XService 不通过@Autowire 使用左右(只需要删除它):

所以我尝试运行 AControllerTest 我得到以下错误:

java.lang.IllegalStateException: 无法加载 ApplicationContext 在 org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124) .. .. 在 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206) 造成的: org.springframework.beans.factory.UnsatisfiedDependencyException: 创建名为“XService”的 bean 时出错:不满足的依赖关系 通过字段“BRepository”表示;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException: 否 可用的“BRepository”类型的合格 bean:预计至少 1 有资格作为自动装配候选者的 bean。依赖注解: @org.springframework.beans.factory.annotation.Autowired(required=true) .. .. 在 org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:120) 在 org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98) 在 org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116) ... 26 更多原因: org.springframework.beans.factory.NoSuchBeanDefinitionException: 否 可用的“BRepository”类型的合格 bean:预计至少 1 有资格作为自动装配候选者的 bean。依赖注解: @org.springframework.beans.factory.annotation.Autowired(required=true) 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1493) 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104) 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) 在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585) ... 44 更多

我的假设是在测试期间启动的上下文比它应该启动的更多。问题是我怎样才能防止这种情况发生?这意味着仅启动 AControler 的上下文,仅此而已?我认为基于@WebMvcTest(AController.class) 它应该已经受到限制,看起来情况并非如此......

【问题讨论】:

How to exclude *AutoConfiguration classes in Spring Boot JUnit tests?的可能重复 【参考方案1】:

引用的答案并没有真正回答我的问题,但在上下文中 hint 给了我解决方案。这意味着在我的测试中添加以下内容:

所以我必须添加@OverrideAutoConfiguration(enabled=true)

@RunWith(SpringRunner.class)
@WebMvcTest(OrgtFarbenController.class)
@OverrideAutoConfiguration(enabled=true)
public class AControllerTest 
...

【讨论】:

以上是关于使用 @WebMvcTest 测试中的 ApplicationContext 异常的主要内容,如果未能解决你的问题,请参考以下文章

在 Spring Boot 测试类上使用 @WebMvcTest 注释时出错

如何使用@WebMvcTest 春季测试在模拟服务中注入模拟的restTemplate

@WebMVCTest中的404问题分析

在 Spring Boot 1.4 MVC 测试中使用 @WebMvcTest 设置 MockMvc

SpringBoot @WebMvcTest,自动装配 RestTemplateBuilder

如何将 @WebMvcTest 用于单元测试 POST 方法?