我在Spring启动项目中为以下类编写了端到端测试,但由于org.springframework.beans.factory.NoSuchBeanDefinitionException
我收到No qualifying bean of type 'com.boot.cut_costs.service.CustomUserDetailsService' available
错误。
@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();
}
}
我认为发生此错误是因为它在测试环境中弹出上下文的加载方式与开发/生产环境相同。我该如何解决这个问题?
修改1
我的Spring启动应用程序入口点为App.java
:
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
答案 0 :(得分:2)
@WebMvcTest
仅加载控制器配置。这就是为什么你有这个DI错误(有了它,你必须为你的服务提供模拟)。因此,如果您需要注入服务,可以使用@SpringBootTest
。
如果您使用@SpringBootTest
,则还必须使用@AutoConfigureMockMvc
配置MockMvc
。
答案 1 :(得分:0)
您需要使用测试类上的@ContextConfiguration批注拉入为bean扫描组件的配置。
这可能会加载不需要的配置,甚至可能导致测试失败,因此更安全的方法是自己编写配置类,只需要运行测试所需的内容(可能只是您的bean的相关组件扫描)。如果将此配置类编写为测试类的静态内部类,则可以通过仅使用不带参数的@ContextConfiguration注释来提取此配置。
@ContextConfiguration
public class MyTestClass {
@Test
public void myTest() {
...
}
@Configuration
@ComponentScan("my.package")
public static class MyTestConfig {
}