2017-09-28 82 views
2

我有多個控制器,我的理解是通過在@WebMvcTest中指定一個控制器,其他控制器不會加載到上下文中。來自docs如何在使用Spring Boot進行測試時從我的上下文中排除其他@Controller @WebMvcTest

控制器 - 指定要測試的控制器。如果應將所有@Controller bean添加到應用程序上下文中,可以留空。

我的第一個控制器

@Controller 
public class MyController { 

    @Autowired 
    private MyService myService; 

    private final Logger logger = Logger.getLogger(this.getClass()); 

    @RequestMapping(value = "/", method = RequestMethod.GET) 
    public @ResponseBody ResponseEntity<String> index() { 
     try { 
      myService.get(); 
      return new ResponseEntity<String>(HttpStatus.OK); 
     } catch (Exception e) { 
      logger.error(e); 
      e.printStackTrace(); 
     } 
     return new ResponseEntity<String>("REQUEST FAILED", HttpStatus.INTERNAL_SERVER_ERROR); 
    } 

} 

我的其他控制器

@Controller 
public class MyOtherController { 

    @Autowired 
    private MyOtherService myOtherService; 

    etc... 
} 

我爲我的控制器

@RunWith(SpringRunner.class) 
@WebMvcTest(controllers = { MyController.class }, secure = false) 
@ActiveProfiles({ "test" }) 
public class MyControllerTest { 

    @Autowired 
    private MockMvc mockMvc; 

    @MockBean 
    MyService myService; 

    @Test 
    public void testBaseReq() throws Exception { 
     Testing dummyData = new Testing(); 
     dummyData.setData("testing"); 
     when(myService.get(anyInt())).thenReturn(dummyData); 

     this.mockMvc.perform(get("/")).andDo(print()).andExpect(status().isOk()); 
    } 
} 

但是當我運行這個測試,它沒有試圖加載測試MyOtherContoller whe的bean MyOtherService n加載上下文。

2017-09-28 11:50:11.687 DEBUG 16552 --- [   main] o.s.b.f.s.DefaultListableBeanFactory  : Creating shared instance of singleton bean 'myOtherController' 
2017-09-28 11:50:11.687 DEBUG 16552 --- [   main] o.s.b.f.s.DefaultListableBeanFactory  : Creating instance of bean 'myOtherController' 
2017-09-28 11:50:11.687 DEBUG 16552 --- [   main] o.s.b.f.annotation.InjectionMetadata  : Registered injected element on class [my.package.other.myOtherController]: AutowiredFieldElement for private my.package.other.myOtherService my.package.other.myOtherController.myOtherService 
2017-09-28 11:50:11.687 DEBUG 16552 --- [   main] o.s.b.f.s.DefaultListableBeanFactory  : Eagerly caching bean 'myOtherController' to allow for resolving potential circular references 
2017-09-28 11:50:11.687 DEBUG 16552 --- [   main] o.s.b.f.annotation.InjectionMetadata  : Processing injected element of bean 'myOtherController': AutowiredFieldElement for private my.package.other.myOtherService my.package.other.myOtherController.myOtherService 
2017-09-28 11:50:11.688 DEBUG 16552 --- [   main] o.s.b.f.s.DefaultListableBeanFactory  : Creating shared instance of singleton bean 'myOtherService' 
2017-09-28 11:50:11.688 DEBUG 16552 --- [   main] o.s.b.f.s.DefaultListableBeanFactory  : Creating instance of bean 'myOtherService' 
2017-09-28 11:50:11.689 DEBUG 16552 --- [   main] o.s.b.f.annotation.InjectionMetadata  : Registered injected element on class [my.package.other.myOtherService]: AutowiredFieldElement for private my.package.other.myOtherMapper my.package.other.myOtherService.myOtherMapper 
2017-09-28 11:50:11.689 DEBUG 16552 --- [   main] o.s.b.f.annotation.InjectionMetadata  : Registered injected element on class [my.package.other.myOtherService]: AutowiredFieldElement for private ie.aib.services.coredemo.FinancialsRegionService my.package.other.myOtherService.financialsRegionService 
2017-09-28 11:50:11.689 DEBUG 16552 --- [   main] o.s.b.f.s.DefaultListableBeanFactory  : Eagerly caching bean 'myOtherService' to allow for resolving potential circular references 
2017-09-28 11:50:11.689 DEBUG 16552 --- [   main] o.s.b.f.annotation.InjectionMetadata  : Processing injected element of bean 'myOtherService': AutowiredFieldElement for private my.package.other.myOtherMapper my.package.other.myOtherService.myOtherMapper 
2017-09-28 11:50:11.690 WARN 16552 --- [   main] o.s.w.c.s.GenericWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myOtherController': Unsatisfied dependency expressed through field 'myOtherService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myOtherService': Unsatisfied dependency expressed through field 'myOtherMapper'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'my.package.other.myOtherMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 

我以爲指定控制器在WebMvcTest註釋中進行測試會限制它到只有控制器的加載。但是它試圖加載另一個控制器,並且因爲它的bean沒有被模擬,所以它失敗了。

我錯過了什麼或者我的理解不正確?我想我應該只能爲受測試的控制器模擬bean。我也嘗試過一個excludeFilter特別排除其他控制器的軟件包,但沒有更改錯誤。

+0

什麼是您的應用程序類的樣子? –

回答

3

請確保Application.class測試回升,不含@ComponentScan註解。例如,這是你的包結構

abc-project 
    +--pom.xml 
    +--src 
    +-- main 
     +-- com 
     +-- abc 
      +-- Application.java 
      +-- controller 
      +-- MyController.java 
    +-- test 
     +-- com 
     +-- abc 
      +-- Application.java 
      +-- controller 
      +-- MyControllerTest.java 

Application.java測試應類似於此示例中,

@SpringBootApplication 
public class Application { 
    public static void main(String[] args) throws Exception { 
     SpringApplication.run(Application.class, args); 
    } 
} 
+0

謝謝@Indra,我認爲這是我的問題。我有一個\ @ComponentScan,因爲我需要顯式過濾來排除包含的jar中的某些組件。我正在尋找改變,所以我有一個單獨的應用程序類,當運行WebMvcTests – MadMurf

+0

謝謝,你做了我的一天。我得到了一個不同的錯誤(Spring試圖實例化一個埋在上下文中的bean,不應該在測試中實例化),並且你的建議也適用於我。 – Antonio

0

my.package.other.myOtherMapper(可能是Mybatis Mapper文件)丟失或未明確初始化。

就我的理解,myOtherService實現類有映射文件沒有正確映射。

您可能必須先映射它們。如果可能,您可以發佈Mapper xml內容。

<context:component-scan base-package="org.example">  
    <context:exclude-filter type="custom" expression="abc.xyz.MyOtherController"/> 
    </context:component-scan> 
+0

是myOtherMapper不是intiialiased,但它試圖實例化它,因爲它試圖將MyOtherController加載到上下文中。如果該控制器被排除在上下文之外(我認爲它應該是這樣),則不會查找myOtherService,因此不會查找myOtherMapper。 – MadMurf

+0

我可以通過在MyOtherService的測試中添加@MockBean來避開它,但我不應該嘲笑每一項服務來測試僅使用一項服務的Controller。 – MadMurf

+0

試試這個 https://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/beans。html#beans-scanning-filters –

相關問題