Strut 2.3.1.2 单元测试,如何使用 getContext() 删除 Spring 依赖与 NPE [英] Strut 2.3.1.2 Unit test, how to remove Spring codependency vs NPE with getContext()

查看:20
本文介绍了Strut 2.3.1.2 单元测试,如何使用 getContext() 删除 Spring 依赖与 NPE的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚升级到 Struts 2.3.1.2,并且在 JUnit 测试方面遇到了一些问题.

I'm just upgrading to Struts 2.3.1.2, and having a few issues with JUnit tests.

我的旧测试代码是这样的......

My old test code was like this....

public class HomeActionTest  {

    @Test
    public void testUserNameErrorMessage() throws Exception {
     HomeAction action = new HomeAction();
     setupMocks(action);
     action.execute();
    }
}

action类的execute方法有代码

The action class's execute method has the code

    String text = getText(GLOBAL_SELECT);

这会在 LocalizedTextUtil 中导致 NullPointerException,因为它调用...

This causes a NullPointerExeception though in LocalizedTextUtil since it calls...

   ActionContext.getContext()

现在我可以尝试这样做......

Now I could try and do this...

  ActionContext.setContext(new ActionContext(new HashMap()));

但是我会得到一个 NullPointerException,因为上下文中的 Valuestack 是空的.我可以继续尝试解决这些问题,但这似乎是一项徒劳的任务.一定有更好的办法?!?

But then I'll get a NullPointerException since the Valuestack from the context is null. I could go on and on trying to fix these problems, but it seems like a futile task. There must be a better way?!?

嗯……

我遵循新的 Struts 2.3.xx测试文档

我的 struts.xml 与 spring 连接.

My struts.xml is wired with spring.

 <action name="secure/home" class="homeAction" method="execute">
            <result>home.jsp</result>
            <result name="input">home.jsp</result>
        <result name="error">error.jsp</result>
 </action>

我的测试课

public class HomeActionTest extends StrutsSpringTestCase   {

    @Test
    public void testUserNameErrorMessage() throws Exception {
        ActionProxy proxy = getActionProxy("/secure/home");

        // setup the session
        Map<String, Object> session = new HashMap<String, Object>();  
        ActionContext actionContext = proxy.getInvocation().getInvocationContext();  
        actionContext.setSession(session);  

        HomeAction homeAction = (HomeAction) proxy.getAction();

        proxy.execute();
    }
}

但这意味着我得到了一个完全填充的 Spring 注入的 Action 类!大多数人会说是的!!!"此时.

But this now means I get a fully populated Spring injected Action class! Most people would saying "YEA!!!" at this point.

我的问题是这不是一个 UNIT 测试类,它现在一直调用到 DB 层,因为它是运行时的接线方式.

My problem is that this isn't a UNIT test class, its now making calls all the way down to the DB layer since that's how its wired for run-time.

所以这是我的问题,我知道我花了一些时间来解决它,是否有可能获得一个可以访问所需资源的 Action 类(用于方法调用,例如 getText()),但不是所有的 Spring 都连接好了?

So here is my question, I know I've taken a while to get to it, is it possible to get an Action class that has access to resources it needs (for method calls such as getText()), but is not all Spring wired up?

目前,我很想走反射路线以删除所有与我的操作匹配的 setServicexxxx 方法,至少那时我会在运行测试时得到 NullPointerException 并且我可以模拟该服务,但这只是错误的.我希望我的测试快速,而不是花费 2 秒来启动 Spring 上下文.

For the moment I'm tempted to go the refection route to remove all methods that match setServicexxxx on my action, at least then I'd get a NullPointerException on running the test and I can mock out that service, but that's just wrong. I want my tests to be FAST, not spend 2 seconds starting up the Spring context.

Struts2.3 是如何产生一个不遵循单元测试原则的基础测试类的?

How did Struts2.3 end up with a Base test class that doesn't follow the mantra of what a Unit test is?

这在 Struts 2.0.9 (xwork-2.0.3.jar) 中一切正常.

This was all fine in Struts 2.0.9 (xwork-2.0.3.jar).

我错过了什么?

推荐答案

您确实应该尽可能快地进行单元测试(否则,没有 TDD).所以你应该做最小的struts设置:(我正在使用mockito,我在一个静态块中有这段代码,完整的代码在这个要点)

You should indeed keep your unit test as fast as possible (otherwise, no TDD). So you should do the minimum struts setup: (I'm using mockito and I have this code in a static block, full code in this gist)

ActionContext actionContext = mock(ActionContext.class);
ServletContext servletContext = mock(ServletContext.class);
when(actionContext.getLocale()).thenReturn(Locale.FRENCH);
ValueStack valueStack = mock(ValueStack.class);
Map<String, Object> context = new HashMap<String,Object>();
Container container = mock(Container.class);
XWorkConverter conv = mock(XWorkConverter.class);
when(container.getInstance(XWorkConverter.class)).thenReturn(conv);
when(conv.convertValue(any(Map.class), any(Object.class), any(Class.class))).thenAnswer(new Answer<Object>() {
    public Object answer(InvocationOnMock invocation) throws Throwable {
        log.info(invocation.getArguments()[1].toString());
        return "VALUE";
    }

});
context.put(ActionContext.CONTAINER, container);
when(valueStack.getContext()).thenReturn(context);
when(actionContext.getValueStack()).thenReturn(valueStack);
ServletActionContext.setContext(actionContext);
ServletActionContext.setServletContext(servletContext);

这篇关于Strut 2.3.1.2 单元测试,如何使用 getContext() 删除 Spring 依赖与 NPE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆