问题描述
当我尝试实现WebMvcTest时,它将尝试实例化每个应用程序控制器,而不只是实例化@WebMvcTest
批注中指示的控制器。
我没有运气或成功,但已阅读以下文章:
- Spring Boot Testing @WebMvcTest for a Controller appears to load other controllers in the context
- @WebMvcTest fails with java.lang.IllegalStateException: Failed to load ApplicationContext
- @WebMvcTest creating more than one Controller for some reason
- Test slice with @WebMvcTest is loading a substantial amount of controllers unrelated with the target
这是我发现与代码相关的部分
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
@RestController
@RequestMapping("/api/complaints/{id}/comments")
public class CommentController {
@PostMapping
public CommentJson comment(@PathVariable String id,@RequestBody CommentCommand command) {
throw new UnsupportedOperationException("Method not implemented yet");
}
}
@WebMvcTest(CommentController.class)
class CommentControllerTest extends AbstractTest {
@Autowired
mockmvc mockmvc;
// ...
}
Parameter 0 of constructor in com.company.package.controller.ComplaintController required a bean of type 'com.company.package.service.Complaints' that Could not be found.
@RestController
@RequestMapping("/api/complaints")
@requiredArgsConstructor
@ControllerAdvice()
public class ComplaintController {
private final Complaints complaints;
// ... other controller methods
@ExceptionHandler(ComplaintNotFoundException.class)
public ResponseEntity<Void> handleComplaintNotFoundException() {
return ResponseEntity.notFound().build();
}
}
@ExtendWith(MockitoExtension.class)
public abstract class AbstractTest {
private final Faker faker = new Faker();
protected final Faker faker() {
return faker;
}
// ... other utility methods
}
我发现运行Web Mvc测试的唯一方法是模拟每个控制器对所有@WebMvcTest
的依赖,这非常繁琐。
我在这里想念东西吗?
解决方法
在仔细查看您的ComplaintController
时,您会用@ControllerAdvice
进行注释
@WebMvcTest
的Javadoc对测试中的Spring Context的相关MVC bean进行了以下说明:
/**
* Annotation that can be used for a Spring MVC test that focuses <strong>only</strong> on
* Spring MVC components.
* <p>
* Using this annotation will disable full auto-configuration and instead apply only
* configuration relevant to MVC tests (i.e. {@code @Controller},* {@code @ControllerAdvice},{@code @JsonComponent},* {@code Converter}/{@code GenericConverter},{@code Filter},{@code WebMvcConfigurer}
* and {@code HandlerMethodArgumentResolver} beans but not {@code @Component},* {@code @Service} or {@code @Repository} beans).
* ...
*/
因此,任何@ControllerAdvice
都是此MVC上下文的一部分,因此这是预期的行为。
要解决此问题,您可以将ComplaintController
中的异常处理提取到不依赖于任何其他Spring Bean的专用类中,并且可以在不模拟任何内容的情况下对其进行实例化。
PS: all 一词在您的问题 WebMvcTest尝试加载每个应用程序控制器的标题内具有误导性。