2017-07-19 208 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”进行了扩展 –