Mockito:在void方法中填充不同的值

时间:2012-07-24 05:20:08

标签: java unit-testing mockito

我正在使用Mockito进行单元测试。我需要模拟一个填充一些输入的void方法。 非常天真的例子:

class Something {
   AnotherThing thing = new AnotherThing();
   public int doSomething(Stuff stuff)
   {
      thing.doThing(stuff);
      if(thing.getName().equals("yes")){
        return 1;
      }
      else {
        return 2;
      }
   }
}

class AnotherThing() {
   public void doThing(Stuff stuff){
       if(stuff.getName().equals("Tom")) {
          stuff.setName("yes");
       }
       else {
          stuff.setName("no");
       }
   }
}

class Stuff()
{
   String name;
   // name getters and setters here
}

在这种情况下,我会尝试模仿AnotherThing来测试Something

但是,我在我测试的类中多次调用这个void方法。我每次打电话都需要不同的“Answer”。我的意思是,我想调用void方法在每次调用时执行不同的操作。

我查看了API,无法找到解决方案。这对Mockito来说是否可能?

5 个答案:

答案 0 :(得分:4)

你需要的是一个Mockito Answer对象。这是一个包含一些功能的对象,您可以在调用mock的方法时运行这些功能。查看doAnswer的Mockito文档以获取更多详细信息;但基本上你想要的是这样的。

  doAnswer(new Answer<Object>(){
        @Override
        public Object answer(InvocationOnMock invocation){
           Object[] arguments = invocation.getArguments();
           Stuff argument = (Stuff) arguments[0];
           if(stuff.getName().equals("Tom")) {
              stuff.setName("yes");
           }
           else {
              stuff.setName("no");
           }
           return null;
        }
     }).when(mockObject).doThing(any(Stuff.class));

答案 1 :(得分:2)

Mockito让你可以连续拨打电话。我想这就是你需要的。以下是mockito documentation中必要部分的链接。

您可以这样写:

Mockito.when(mockAnotherThing.doThing(stuff)).thenReturn("yes").thenReturn("no");

在第一次发生反应之后,这个模拟者将返回“是”并且在第二次 - “不”之后。

顺便说一下,我认为你需要像这样更改你的示例代码(在其他情况下它不会起作用):

class AnotherThing() {
   public String doThing(Stuff stuff){
       if(stuff.getName().equals("Tom")) {
         return "yes";
       }
       else {
          return "no";
       }
   }
}

答案 2 :(得分:0)

你不能使用equals,因为返回类型是void要么将doThing()的返回类型更改为String,然后像这样模拟

 Anotherthing anotherthing = mock(Anotherthing.class)
 when(anotherThing.doThing(isA(Stuff.class))).thenReturn("yes").thenReturn("no");

你可能想要多次模拟这个连续两次调用后的最后一个存根值(“no”返回);

答案 3 :(得分:0)

为什么需要不同的Answer?你可以使用同一个:

doAnswer(new Answer<Object>(){
    private int call;
    @Override
    public Object answer(InvocationOnMock invocation){
        ...
        call = call + 1;
        if (call % 2 == 0) {
        //do something
        } else {
        //another behavior 
        }
    }
 }).when(mockObject).doThing(any(Stuff.class));

答案 4 :(得分:0)

有一个simpler way

doNothing().doNothing().doThrow(new RuntimeException()).when(mock).someVoidMethod();

通过这种方式,对方法的多次调用可以做不同的事情。