问题
Here's my test case for a Spring Controller
@RunWith(SpringRunner.class)
@WebMvcTest(value = MyController.class)
public class MyControllerTest {
@MockBean
private MyService myService;
}
So this is a unit test specifically for the methods in MyController. But when I run the test, Spring appears to begin instantiating OtherController and all of it's dependencies.
I have tried updating the above as
@RunWith(SpringRunner.class)
@WebMvcTest(value = MyController.class, excludeFilters = @ComponentScan.Filter(value= OtherController.class, type = FilterType.ANNOTATION))
public class MyControllerTest {
...
}
But spring still appears to wire it. Here's the error thrown by Spring as it tries to instantiate OtherController when I run the above test specifically.
2017-01-06 12:09:46.207 WARN 18092 --- [ 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 'otherController' defined in file [C:\..OtherController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'getOtherService' defined in com.my.myApplication: Unsatisfied dependency expressed through method 'getOtherService' parameter 0org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'getOtherService' defined in com.myOrg.MyServiceApplication: Unsatisfied dependency expressed through method 'getPositionService' parameter 0
What could be causing this?
回答1:
Chances are that you are triggering the bean scanning by accident via a @Componentscan
or the likes.
For instance, as explained in this answer, Spring may be detecting your "production" @SpringBootApplication
Application
class, with all the component scans it brings about. If so make sure you "overwrite" your "production" Application class with your "test" one putting...
@SpringBootApplication
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
...in a location that would override the "Production" Application.
For instance, if your IDE doesn't get messed by class name clashes:
"production" -> src/main/java/com/mycompany/Application.java
-> src/main/java/com/mycompany/controllers/MyController.java
"test" -> src/test/java/com/mycompany/Application.java
-> src/test/java/com/mycompany/controllers/MyControllerTest.java
As an alternative I also have found that in my case this works as well (i.e. placing the Application in the test controllers folder)
"production" -> src/main/java/com/mycompany/Application.java
-> src/main/java/com/mycompany/controllers/MyController.java
"test" -> src/test/java/com/mycompany/controllers/Application.java
-> src/test/java/com/mycompany/controllers/MyControllerTest.java
来源:https://stackoverflow.com/questions/41512074/spring-boot-testing-webmvctest-for-a-controller-appears-to-load-other-controlle