Spring 依赖项失败的控制器测试
Spring controller testing with dependencies failing
我有以下控制器class:
@Controller
public class HelloController {
private final HelloService service;
public HelloController(HelloService service) {
this.service = service;
}
@RequestMapping("/hello")
public @ResponseBody String greeting() {
return service.greet();
}
}
如您所见,它接受一个依赖项。这一切在服务器中运行良好。但是,在测试时,它失败了:
@RunWith(SpringRunner.class)
@WebMvcTest(HelloController.class)
public class WebLayerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void shouldReturnDefaultMessage() throws Exception {
this.mockMvc.perform(get("/hello")).andDo(print()).andExpect(status().isOk())
.andExpect(content().string(containsString("Hello World")));
}
}
下面是target/surefire-reports/
中日志文件的输出
-------------------------------------------------------------------------------
Test set: biz.martyn.footy.WebLayerTest
-------------------------------------------------------------------------------
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 2.278 s <<< FAILURE! - in biz.martyn.footy.WebLayerTest
shouldReturnDefaultMessage(biz.martyn.footy.WebLayerTest) Time elapsed: 0.005 s <<< ERROR!
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'helloController' defined in file [/home/martyn/eclipse-workspace/Footy/target/classes/biz/martyn/footy/controller/HelloController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'biz.martyn.footy.service.HelloService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'biz.martyn.footy.service.HelloService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
我知道 @MockBean
允许我创建依赖项的模拟,但在我不想模拟它的情况下?在这里,我很高兴真正的依赖实例可以正常使用。或者,是因为我只测试 Web 层,它没有像 运行 完整应用程序那样实例化控制器吗?
更新
我还尝试了 @Autowired
注入而不是构造函数。我的应用程序可以运行,因此将依赖项引入控制器,但测试失败。以下是更新后的控制器:
@Controller
public class HelloController {
@Autowired
private HelloService service;
@RequestMapping("/hello")
public @ResponseBody String greeting() {
return service.greet();
}
}
@WebMvcTest
将禁用完全自动配置,而是仅应用与 MVC 测试相关的配置(即 @Controller
、@ControllerAdvice
、@JsonComponent
、Converter/GenericConverter 、Filter、WebMvcConfigurer 和 HandlerMethodArgumentResolver beans 但不是 @Component
、@Service
或 @Repository
beans,因此您必须使用 @MockBean
来满足依赖关系。
我有以下控制器class:
@Controller
public class HelloController {
private final HelloService service;
public HelloController(HelloService service) {
this.service = service;
}
@RequestMapping("/hello")
public @ResponseBody String greeting() {
return service.greet();
}
}
如您所见,它接受一个依赖项。这一切在服务器中运行良好。但是,在测试时,它失败了:
@RunWith(SpringRunner.class)
@WebMvcTest(HelloController.class)
public class WebLayerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void shouldReturnDefaultMessage() throws Exception {
this.mockMvc.perform(get("/hello")).andDo(print()).andExpect(status().isOk())
.andExpect(content().string(containsString("Hello World")));
}
}
下面是target/surefire-reports/
中日志文件的输出-------------------------------------------------------------------------------
Test set: biz.martyn.footy.WebLayerTest
-------------------------------------------------------------------------------
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 2.278 s <<< FAILURE! - in biz.martyn.footy.WebLayerTest
shouldReturnDefaultMessage(biz.martyn.footy.WebLayerTest) Time elapsed: 0.005 s <<< ERROR!
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'helloController' defined in file [/home/martyn/eclipse-workspace/Footy/target/classes/biz/martyn/footy/controller/HelloController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'biz.martyn.footy.service.HelloService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'biz.martyn.footy.service.HelloService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
我知道 @MockBean
允许我创建依赖项的模拟,但在我不想模拟它的情况下?在这里,我很高兴真正的依赖实例可以正常使用。或者,是因为我只测试 Web 层,它没有像 运行 完整应用程序那样实例化控制器吗?
更新
我还尝试了 @Autowired
注入而不是构造函数。我的应用程序可以运行,因此将依赖项引入控制器,但测试失败。以下是更新后的控制器:
@Controller
public class HelloController {
@Autowired
private HelloService service;
@RequestMapping("/hello")
public @ResponseBody String greeting() {
return service.greet();
}
}
@WebMvcTest
将禁用完全自动配置,而是仅应用与 MVC 测试相关的配置(即 @Controller
、@ControllerAdvice
、@JsonComponent
、Converter/GenericConverter 、Filter、WebMvcConfigurer 和 HandlerMethodArgumentResolver beans 但不是 @Component
、@Service
或 @Repository
beans,因此您必须使用 @MockBean
来满足依赖关系。