Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 279890

Spring Testing - Inject mocked bean with nested bean dependencies

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?

Upvotes: 3

Views: 4398

Answers (2)

Sergey Grigoriev
Sergey Grigoriev

Reputation: 719

You can override a specific bean with a mocked one globally with spring-reinject, see https://github.com/sgri/spring-reinject/wiki/User%27s-Guide

Upvotes: 0

Yugang Zhou
Yugang Zhou

Reputation: 7283

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.

Upvotes: 4

Related Questions