2017-07-19 204 views
0

我正在爲我的Spring啓動項目中的以下類寫一個端到端測試,但我收到org.springframework.beans.factory.NoSuchBeanDefinitionException錯誤,因爲No qualifying bean of type 'com.boot.cut_costs.service.CustomUserDetailsService' available春季啓動jUnit測試失敗,因爲「org.springframework.beans.factory.NoSuchBeanDefinitionException」

@RestController 
public class AuthenticationController { 

    @Autowired 
    protected AuthenticationManager authenticationManager; 
    @Autowired 
    private CustomUserDetailsService userDetailsServices; 
    @Autowired 
    private UserDetailsDtoValidator createUserDetailsDtoValidator; 

    @RequestMapping(value = "/signup", method = RequestMethod.POST) 
    public void create(@RequestBody UserDetailsDto userDetailsDTO, HttpServletResponse response, BindingResult result) { 
     // ... 
     userDetailsServices.saveIfNotExists(username, password, name); 
     // ... 
     if (authenticatedUser != null) { 
      AuthenticationService.addAuthentication(response, authenticatedUser.getName()); 
      SecurityContextHolder.getContext().setAuthentication(authenticatedUser); 
     } else { 
      throw new BadCredentialsException("Bad credentials provided"); 
     } 
    } 
} 

測試類:

@RunWith(SpringRunner.class) 
@WebMvcTest(AuthenticationController.class) 
public class AuthenticationControllerFTest { 

    @Autowired 
    private MockMvc mockMvc; 

    @MockBean 
    private AuthenticationManager authenticationManager; 

    @Test 
    public void testCreate() throws Exception { 
     Authentication authentication = Mockito.mock(Authentication.class); 
     Mockito.when(authentication.getName()).thenReturn("DUMMY_USERNAME"); 
     Mockito.when(
       authenticationManager.authenticate(Mockito 
        .any(UsernamePasswordAuthenticationToken.class))) 
       .thenReturn(authentication); 

     //.... 
     RequestBuilder requestBuilder = MockMvcRequestBuilders 
       .post("/signup") 
      .accept(MediaType.APPLICATION_JSON).content(exampleUserInfo) 
       .contentType(MediaType.APPLICATION_JSON); 

     MvcResult result = mockMvc.perform(requestBuilder).andReturn(); 

     MockHttpServletResponse response = result.getResponse(); 
    } 
} 

我認爲這會發生錯誤,因爲它在測試環境中的Spring上下文不加載的方式作爲開發/生產環境相同。我應該如何解決這個問題?

編輯1個

我的春天啓動的應用程序入口點是App.java

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

我認爲原因也是背景。試試這個: @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {「location/to/test-config.xml」}) –

+0

什麼是「位置」?它指向什麼? –

+0

請參考:http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/resources.html#resources-app-ctx –

回答

1

@WebMvcTest只加載控制器配置。這就是爲什麼你有這個DI錯誤(有了它,你必須爲你的服務提供模擬)。因此,如果您需要注入服務,則可以使用@SpringBootTest

如果使用@SpringBootTest,則還必須使用@AutoConfigureMockMvc來配置MockMvc

0

您需要在該組件的掃描使用您的測試@ContextConfiguration註解你的bean的配置拉類。

這可能會加載不需要的配置,甚至可能會導致測試失敗,因此更安全的方法是自己編寫一個配置類,只需要讓測試運行即可(可能只是相關的組件掃描你的豆)。如果您將此配置類編寫爲測試類的靜態內部類,那麼只需使用不帶參數的@ContextConfiguration註釋就可以取得該配置。

@ContextConfiguration 
public class MyTestClass { 

    @Test 
    public void myTest() { 
    ... 
    } 

    @Configuration 
    @ComponentScan("my.package") 
    public static class MyTestConfig { 
    } 
+0

這是一個彈簧啓動應用程序,因此它沒有配置文件來拉入。 –

+0

@ArianHosseinzadeh啊,以及我已經更新了我的答案。你仍然應該可以這樣做,以便像這樣在你的測試環境中手動強制Spring引導應用程序進行組件掃描。 – Plog

+0

我在測試類中添加了@ContextConfiguration(classes = {App.class}),並沒有解決問題。我編輯了我的問題,並對「App.java」進行了擴展 –