在类中使用Mockito注入模拟,从父类中窥探方法

时间:2015-01-22 10:49:39

标签: java unit-testing junit mockito

我在使用Spring和Struts的Java项目中使用Mockito,我在测试操作方面遇到了问题。

我没有使用Struts2 jUnit插件来使用这种方法节省测试时间:Strut 2.3.1.2 Unit test, how to remove Spring codependency vs NPE with getContext()

问题是在我的行动中,当调用 getText()时,我有一个NullPointerException。

我正在试图监视这个方法,它继承自 ActionSupport ,但我找不到办法,因为该操作在测试中使用 InjectMocks 进行了注释。 / p>

这是一个简单的类示例:

父:

public class ActionSupport {
    public String getText(String  aTextName){
        return this.getTextProvider().getText(aTextName);
    }
}

我的行动:

public class MyAction extends ActionSupport {
    @Autowired private IMyService myService;

    public String execute(){
        getText("SomeText");
        myService.something();
        return SUCCESS;
    }
}

测试:

@RunWith(MockitoJUnitRunner.class)
public class MyClassTest {
    @Mock private IMyService myService;
    @InjectMocks private MyAction myAction;

    @Before
    public void before() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void test() {
        myAction.execute();
    }
}

我遇到了这个例外:

java.lang.NullPointerException
    at com.opensymphony.xwork2.util.TextParseUtil.translateVariables(TextParseUtil.java:167)
    at com.opensymphony.xwork2.util.TextParseUtil.translateVariables(TextParseUtil.java:126)
    at com.opensymphony.xwork2.util.TextParseUtil.translateVariables(TextParseUtil.java:48)
    at com.opensymphony.xwork2.util.LocalizedTextUtil.getDefaultMessage(LocalizedTextUtil.java:663)
    at com.opensymphony.xwork2.util.LocalizedTextUtil.findText(LocalizedTextUtil.java:534)
    at com.opensymphony.xwork2.util.LocalizedTextUtil.findText(LocalizedTextUtil.java:362)
    at com.opensymphony.xwork2.TextProviderSupport.getText(TextProviderSupport.java:208)
    at com.opensymphony.xwork2.TextProviderSupport.getText(TextProviderSupport.java:123)
    at com.opensymphony.xwork2.ActionSupport.getText(ActionSupport.java:103)
    at es.MyAction.execute(MyAction.java:148)

如果我使用 @Spy 注释 MyAction 维护 @InjectMocks ,我有一个 StackOverflowError 。< / p>

我如何只侦察 ActionSupport.getText()并让 mockito 为我的行动注入嘲笑?

1 个答案:

答案 0 :(得分:3)

我会避免使用@InjectMocks,因为它会无声地失败。

只需使用MyAction(即构造函数注入)向@Autowired添加构造函数即可。这也有助于保证所需的依赖性。

您不需要initMocksMockitoJUnitRunner

public class MyAction extends ActionSupport {

    private IMyService myService;

    @Autowired
    public MyAction(MyService myService) {
        this.myService = myService;
    }

    public String execute(){
        getText("SomeText");
        myService.something();
        return SUCCESS;
    }
}

@RunWith(MockitoJUnitRunner.class)
public class MyClassTest {

    @Mock
    private IMyService myService;

    private MyAction myAction;

    @Before
    public void setup() {
        myAction = spy(new MyAction(myService));
    }

    @Test
    public void test() {

        assertThat(myAction.execute(), equalTo(Action.SUCCESS));

        verify(myAction, times(1)).getText();

        verify(myService, times(1)).something();
    }
}

InjectMocks fails silently

Constructor injection discussion