How do you use spring injection for unit testing the controller?

I want to test my spring mvc controller.

The controller has a service:

@Autowired UserService userService 

And my user service depends on (autowired) my UserDao and some other services like mongoDb etc.

Now I want the business logic to be tested in my UserService, but of course I want to mock the answers from my UserDao and Mongodb, etc.

How to configure my unit test?

Is it possible to reuse the container xml spring file that has all my beans, etc., or am I creating a new one? (I assume I need to get the spring container here)

Looking for some guidance on this, any lessons will be greatly appreciated.

Update

What seems strange to me is that for my spring controller (which is not implemented with Controller) I managed to access my private varialbe to manually install my service, for example:

 @Controller public class UserController { @Autowired UserService userService; } 

And in my unit test, I could do:

 UserController controller = new UserController(); controller.userService = .... 

But for my UserService, which has a UserDao answering machine, I cannot access the userDao property:

 UserService userService = new UserServiceImpl(); userService.userDao = .... // not available 

This makes sense since it is private, but how does it work for my controller?

+7
source share
3 answers

Spring Framework has very interesting features for testing. You can see the Spring reference guide . It can provide DI even in your JUnit test class.

 @RunWith(SpringJUnit4ClassRunner.class) // ApplicationContext will be loaded from "/applicationContext.xml" and "/applicationContext-test.xml" // in the root of the classpath @ContextConfiguration(locations={"/applicationContext.xml", "/applicationContext-test.xml"}) public class MyTest { // class body... } 

In short, you can use your own applicationContext.xml or even define a new one for testing. I personally use a different one, as I am defining a different data source for testing.

+5
source

What seems strange to me is that for my spring controller (which is not implemented with Controller) I managed to access my private varialbe to manually install my service, for example:

This is easy: the variable is not closed.

It has default visibility ("private package"). This means that you can access them from all classes of the same package.

So, if you have a common structure, then the controller and the test case of the controller are in the same package. Therefore, you can change the controller fields ("private"). But the test case of the controller and the service are not in the same package, so you cannot access the fields of the "private" service.

+4
source

Is it possible to reuse the spring container XML file that has all my beans or am I creating a new one? (I assume I need to get the spring container here)

I would advise creating a new xml file. You end up duplicating a lot of things and it will be difficult to maintain. Configuration files will be distributed. You install the configuration required for the tests in a different xml and should not even be deployed in your production box. If you use the configuration for beans, you can use the mechanism suggested by @Trein.

For testing spring contrller in general, you may also find this SO thread useful.

Hope this helps.

+1
source

All Articles