如何使用弹簧注射器对控制器进行单元测试?

时间:2012-01-02 15:14:08

标签: java spring junit easymock

我想测试我的spring mvc控制器。

控制器有一项服务:

@Autowired
UserService userService

我的用户服务依赖于(自动装配)我的UserDao和其他一些服务,如mongoDb等。

现在我希望在我的UserService中测试业务逻辑,但是当然我想模拟来自UserDao和Mongodb等的响应。

如何正确设置单元测试?

我可以重新使用包含所有bean等的弹簧容器的xml文件,还是创建一个新的?(我假设我必须在这里涉及弹簧容器)

寻找关于此的一些指导,我们将非常感谢任何教程。

更新

我觉得奇怪的是,对于我的spring控制器(未通过Controller实现),我能够访问我的私有变量来手动设置我的服务,即:

@Controller
public class UserController {

   @Autowired
   UserService userService;
}

在我的单元测试中,我可以做到:

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

但对于我的UserService,其中有UserDao自动装配,我无法访问userDao属性:

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

它是有意义的,因为它是私有的,但它如何为我的控制器工作?

3 个答案:

答案 0 :(得分:5)

Spring框架具有非常有趣的测试功能。你可以看看Spring reference guide。它甚至可以在你的JUnit测试类中提供DI。

@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...
}

简而言之,您可以使用自己的 applicationContext.xml ,甚至可以定义一个新的仅用于测试。我个人使用另一个,因为我定义了另一个专用于测试目的的dataSource。

答案 1 :(得分:4)

  

我觉得奇怪的是,对于我的spring控制器(未通过Controller实现),我能够访问我的私有变量来手动设置我的服务,即:

这很简单:变量不是私有的。

它具有默认可见性(“包私有”)。这意味着您可以从同一个包的所有类中访问它们。

因此,如果您有一个共同的结构,那么控制器和控制器测试用例在同一个包中。因此,您可以修改(“包私有”)控制器字段。但控制器测试用例和服务不在同一个打包中,因此您无法访问(“包私有”)服务字段。

答案 2 :(得分:1)

  

我可以重复使用包含所有bean的spring容器的xml文件吗?   等我还是要创建一个新的? (我假设我必须得到春天   这里涉及的容器)

我建议不要创建新的xml文件。你最终会复制很多东西而且很难维护。配置文件会激增。您将测试所需的配置放在不同的xml中,甚至不应该将其部署到生产框中。就使用bean的配置而言,您可以使用@Trein建议的机制。

一般来说,对于测试弹簧控制器,您可能会发现这个SO Thread很有用。

希望有所帮助。