How do you use spring's injection for unit testing a controller?

Blankman picture Blankman · Jan 2, 2012 · Viewed 9.8k times · Source

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 ofcourse I want to mock the responses from my UserDao and Mongodb etc.

How do I setup my unit test correctly?

Can I re-use the spring container's xml file that has all my beans etc. or do I create a new one? (I'm assuming I have to get the spring container involved here)

Looking for some guidance on this, any tutorials would be greatly appreciated.

Update

What I find strange is that for my spring controller (that doesn't implement from Controller) I was able to access my private varialbe to manually set my service, i.e:

@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 UserDao autowired, I can't access the userDao property:

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

It makes sense since it is private, but how is it working for my controller?

Answer

Trein picture Trein · Jan 2, 2012

Spring framework has very interesting features for testing. You can take a look at 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...
}

Briefly, you can use your own applicationContext.xml or even define a new one just for testing. I personally use a different one since I define another dataSource dedicated for testing purposes.