My application has two controllers. Their structures look like this:
@RestController
public class BooksController {
private final DataService dataService;
private final LibraryBookService libraryBookService;
public BooksController(DataService dataService, LibraryBookService libraryBookService) {
this.dataService = dataService;
this.libraryBookService = libraryBookService;
}
}
@RestController
public class UsersController {
private final DataService dataService;
public UsersController(DataService dataService) {
this.dataService = dataService;
}
}
Both DataService
and LibraryBookService
are beans. They have no dependencies on each other.
I'm trying to write my tests for UsersController, and I'm using @WebMvcTest
. I've got an @MockBean
for the DataService so I can mock its responses:
@WebMvcTest
class UsersControllerTest {
@Autowired
MockMvc mvc;
@MockBean
DataService dataService;
@BeforeEach
void resetMocks() {
Mockito.reset(this.dataService);
}
// ...
}
However when I try to run this, I get an "APPLICATION FAILED TO START" message and a warning that BooksController couldn't autowire its dependencies properly with the stack trace pointing to:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'booksController' defined in file [/path/to/my/project/target/classes/com/example/rest/BooksController.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.LibraryBookService' 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 'com.example.LibraryBookService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
Why does my UserController test care about BooksController and its dependencies (or lack thereof)? I can get past this by adding a MockBean for BooksController like this:
@MockBean
BooksController ignored;
... but this doesn't seem very sustainable. As I add more and more controllers I'm going to have more and more of these irrelevant beans polluting my tests.
Is there an annotation or config I'm missing? Or am I misusing the @WebMvcTest
entirely?
CodePudding user response:
Try specifying the Controller under test as follows:
@WebMvcTest(UsersController.class)
By specifying none, you are telling Spring that all @Controller
beans should be added to the application context and thus the UnsatisfiedDependencyException
you are getting.