我们有带有控制器和服务层的Spring Web层,其服务具有自动装配的bean /服务。我们正试图通过Web层模拟它们来编写服务的集成测试用例。在测试用例中,我们创建了WebAppContext并将其部署在jetty服务器上。在我的测试用例中,我试图从服务器获取上下文并使用反射替换服务以模拟模拟对象。但问题是因为所有都是LAZILY自动装配,当实际的自动装配对象被初始化时,我的模拟被覆盖。
我们需要解决方案在运行测试用例的同时用上下文中的mock对象替换实际的初始化对象。
当我使用getBean(“beanName”)从上下文中获取bean时,bean中的所有自动连接字段都为null,任何原因和我从应用程序上下文中删除了'default-lazy-init'以避免延迟负荷。
见下面的代码,我有depositService&在AccountService中撤销服务。 当我从getBean()获得'Accountservice'时,它将这两个自动装配的varibles返回为null,即 depositService = null& withdrawService = null。
@service
public class AccountServiceImpl implements AccountService{
@autowired
private Depositservice depositService;
@autowired
private WithdrawService withdrawService;
}
答案 0 :(得分:0)
答案 1 :(得分:0)
我通常在测试类路径中使用一些名为相同内容的特定文件来测试Spring上下文覆盖,这些文件在测试期间接管主类路径中的普通bean。然后显然我使用Spring Junit Runner和其他上下文注释来为我的上下文引入我想要的启动文件。
答案 2 :(得分:0)
最后我找到了答案。问题是当spring初始化autowired属性时,它会在它周围创建一个代理对象。因此,每当我们必须将模拟对象设置为任何属性时,我们应该在代理对象中设置它。
以下是代码段:
WebApplicationContext webContext = getWebContextBean();
StaticApplicationContext context = new StaticApplicationContext(webContext);
MockService mockObject = mock(DepositService.class );
AccountServiceImpl service = context.getBean( AccountServiceImpl.class );
ReflectionTestUtils.setField( unwrapProxy(service), "depositService", mockObject );
context.refresh();
UnwrapProxy将具有以下逻辑:
if ( AopUtils.isAopProxy( bean ) && bean instanceof Advised ) {
Advised advised = (Advised)bean;
bean = advised.getTargetSource().getTarget();
}
return bean;
从已部署应用的服务器获取上下文
WebApplicationContext getWebContextBean() {
WebAppContext jettyWebAppContext = (WebAppContext)server.getHandler();
ServletContext servletContext = jettyWebAppContext.getServletHandler().getServletContext();
WebApplicationContext springWebAppContext = WebApplicationContextUtils.getWebApplicationContext( servletContext );
return springWebAppContext;
}