Spring Testing - Inject mocked bean with nested bean dependencies

java, junit, mockito, spring, spring-mvc

Solution

You could use standalone mockMvc if you do want to unit test the controller.

 private MockMvc mockMvc;

 private SomeController controller = new SomeController();
 @Mock 
 private ResourceAdminService resourceAdminService;


 @Before
 public void setup() throws Exception {
    controller.setResourceAdminService(resourceAdminService);
    this.mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
 }

If you still want to setup an ApplicationContext, but it's too annoying with the DI. Maybe you'll interested in this article(http://java.dzone.com/articles/how-use-mockstub-spring). But the Strategy C:Dynamic Injecting will rebuild an ApplicationContext per test which could slow you tests if you have too many @Test methods.

Problem

I have a Bean structure like so (but with many more levels): ``` @Controller public class MyController { @Autowired private MyService myService; } @Service public class MyService { @Autowired private MyDao myDao; } @Repository public class MyDao { } ``` and I want to unit test `MyController` with `MockMvc`. If I create a context that creates a `MyController` instance, it expects a `MyService` instance for injection, which expects a `MyDao` instance, and so on. Even if I mock `MyService` like (no component scan) ``` @Bean public MyController myController() { MyController controller = new MyController (); return controller; } @Bean public MyService myService() { return Mockito.mock(MyService.class); } ``` Spring will see the `@Autowired` for `MyDao` inside `MyService` and try to find one in the context. It will obviously fail and throw an exception. I can create a context that has mocks for each and every one one of my classes, but I'd rather not. Is there any way I can tell Spring not to inject the fields of a bean or a different way of simply injecting the one mock I need in my controller to be tested with `MockMvc`?

Original source