问题
I have a project with two submodules; one is the data access layer the other is the API service. The data access module uses JOOQ and an autowired DSLContext in a service class. Also, I'm using JUnit 5, and Spring Boot 2.2.4.
The QueryService class in the data access module has a member like @Autowired private DSLContext dsl
;
The test class is set up like this:
@SpringBootTest
public class MyServiceTests {
@Autowired
QueryService service;
@Autowired
private DSLContext dsl;
@Test
public void TestDoSomething() throws Exception {
service.selectBusinessEntityRelatedByBusinessEntity("C00001234", mockAuth);
}
}
The tests in this module run correctly. Configuration is read from the application.yaml, and autowire injects either real services or a mock into both my QueryService and the local dsl.
The API service is a different story. If I use the @SpringBootTest annotation with no MVC I can successfully get the tests to inject a local DSLContext with configuration from the application.yaml. Test set up similar to this:
@SpringBootTest
public class CustomersControllerTests {
@Autowired
private Gson gson;
@Autowired
DSLContext dsl;
@Test
public void addCustomerTest() {
}
What I need though is to use @WebMvcTest so that MockMvc is initialized but switching to @WebMvcTest causes injection to fail in the service class implemented in the data access module. The injection fails to find the DSLContext bean within the query service class. I set up the test like this:
@WebMvcTest
public class CustomersControllerTests {
@Autowired
private MockMvc mockMvc;
@Autowired
private Gson gson;
private static final String testSub = "329e6764-3809-4e47-ac48-a52881045787";
@Test
public void addCustomerTest() {
var newCustomer = new Customer().firstName("John").lastName("Doe");
mockMvc.perform(post("/customers").content(gson.toJson(newCustomer)).contentType(MediaType.APPLICATION_JSON)
.with(jwt().jwt(jwt -> jwt.claim("sub", testSub)))).andExpect(status().isNotImplemented());
}
This is the actual error:
2020-02-25 18:14:33.655 WARN 10776 --- [ main] o.s.w.c.s.GenericWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'customersController': Unsatisfied dependency expressed through field '_customersService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'customersService': Unsatisfied dependency expressed through field '_queryService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'queryService': Unsatisfied dependency expressed through field '_dsl'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.jooq.DSLContext' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
So, I know the test application configuration is correct because it works when not using MVC annotation. Also, I can create a DSLContext in the API project tests and I can actually run the API service outside the test.
So, why cant the DSLContext be found when using the MVC test setup?
回答1:
This might be because @WebMvcTest fully disables Spring Boot's Autoconfiguration and only scans in @Controllers and a few other select classes, that you need for your ..well...MVC tests..
The Spring documentation recommends doing this in your case:
If you are looking to load your full application configuration and use MockMVC, you should consider @SpringBootTest combined with @AutoConfigureMockMvc rather than this annotation.
来源:https://stackoverflow.com/questions/60405317/nunit-5-spring-mvc-test-nosuchbeandefinitionexception-for-autowired-dependency-i