Reputation: 668
When I try to implement a WebMvcTest it attempts to instantiate every application controller rather than just the one indicated on the @WebMvcTest
annotation.
Without any luck or success, I've read these articles:
And here are the parts of my code that I found relevant
@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;
// ...
}
When I run the tests it fails with the following error:
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
}
The only way I found to make my Web Mvc Tests run is to mock every dependency of each controller on all @WebMvcTest
which is very tedious.
Am I missing something here?
Upvotes: 1
Views: 1819
Reputation: 12051
While taking a close look at your ComplaintController
, you annotate it with @ControllerAdvice
The Javadoc of @WebMvcTest
says the following about the relevant MVC beans that are part of the Spring Context for your test:
/**
* 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).
* ...
*/
So any @ControllerAdvice
is part of this MVC context and hence that's the expected behaviour.
To fix this you could extract your exception handling out of your ComplaintController
into a dedicated class that does depend on any other Spring Beans and can be instantiated without mocking anything.
PS: The word all is misleading inside the title of your question WebMvcTest attempts to load every application Controller.
Upvotes: 2