Mockito如何使用输出参数模拟void方法?

gul*_*emo 9 java mockito

我有一个void方法"functionVoid"通知参数.

public class MyMotherClass {
 @Inject
 MyClass2 myClass2

 public String motherFunction(){
  ....
  String test = "";
  myClass2.functionVoid(test);

  if (test.equals("")) {
      IllegalArgumentException ile = new IllegalArgumentException(
      "Argument is not valid");
      logger.throwing(ile);
      throw ile;
  }
  ....
 }
}

public class MyClass2 {

public void functionVoid(String output_value)
{ ....
 output_value = "test";

 ....
 }
}
Run Code Online (Sandbox Code Playgroud)

如何在JUnit方法中模拟我的方法"motherFunction"?在我的例子中,"test"变量仍然是空的.

@RunWith(MockitoJUnitRunner.class)
public class MyMotherClassTest {

 @Mock
 private MyClass2 myClass2 ;

 @InjectMock
 private final MyMotherClass myMotherClass = new MyMotherClass ();

 @Test
 public void test(){

  myMotherClass.motherFunction();     

 }
}
Run Code Online (Sandbox Code Playgroud)

Oce*_*ife 18

如果你想模拟当时的返回结果,motherFunction你不必担心方法的内部实现(最终调用functionVoid).你需要做的是向Mockito提供一个指令,说明在motherFunction调用方法时该怎么做,这可以通过带语法的when子句来实现;

    when(mockedObject.motherFunction()).thenReturn("Any old string");
Run Code Online (Sandbox Code Playgroud)

如果这忽略了你试图实现的目的,那么看看如何在文档中模拟void方法并确定是否doAnswer适用于此处,例如;

doAnswer(new Answer<Void>() {

  @Override
  public Void answer(InvocationOnMock invocation) throws Throwable {
    String output_value = invocation.getArguments()[0];
    output_value = "Not blank";
    return null;
  }
}).when(myClass2).functionVoid(anyString());
Run Code Online (Sandbox Code Playgroud)

  • 这是模拟void方法的正确方法,但是不会像上面的示例所示那样,在调用“ functionVoid”之后导致“ test”变量发生变化。 (2认同)

mrj*_*jmh 7

如果你可以改变functionVoid()来接受一个可变对象作为参数,那么你应该能够实现你想要的.

例如,如果您更改functionVoid(),如下所示:

public void functionVoid(StringBuilder output_value)
{ ....
 output_value.append("test");

 ....
 }
Run Code Online (Sandbox Code Playgroud)

并在您的motherFunction中调用它,如下所示:

public String motherFunction(){
  ....
  StringBuilder test = new StringBuilder();
  myClass2.functionVoid(test);

  if (test.toString().equals("")) {
Run Code Online (Sandbox Code Playgroud)

现在修改OceanLife上面的答案,你应该能够做到以下几点:

doAnswer(new Answer<Void>() {

  @Override
  public Void answer(InvocationOnMock invocation) throws Throwable {
    StringBuilder output_value = invocation.getArguments()[0];
    output_value.append("Not blank");
    return null;
  }
}).when(myClass2).functionVoid(any(StringBuilder.class)); 
Run Code Online (Sandbox Code Playgroud)

当然,如果你可以改变functionVoid(),你也可以让它返回一个String而不是void.


Tom*_*sky 5

在我的示例中,“ test”变量仍然为空。

这不是Mockito问题。

看一下这个问题,尤其是这个答案。

其要点是Java是通过值传递的(在上面的链接中对此有更好的解释)。Mockito或Java中的test任何东西都不能使var 变成空字符串。在方法调用之前为空字符串,在调用之后为空字符串。

您可以在方法内更改对象的状态(例如,将对象添加到方法内的集合中),并在退出该方法时查看这些更改,但是您无法更改方法中var引用的对象并期望这些更改“粘住”一旦退出该方法。但是,字符串实际上是不可变的(无状态可更改),因此您甚至无法执行此操作。

因此,test不能在该方法调用中进行任何修改。