当前位置: 首页 > 知识库问答 >
问题:

当使用未定义的参数调用mock时,如何使Mockito引发异常?

莫振
2023-03-14

是否可以在使用非预定义参数调用模拟时引发异常?有答案。返回\u SMART\u null,但这并不是我真正需要的,因为如果null是合法的返回值,它就不起作用,这不会导致NullPointerException,而是以后出错。

编辑:一些背景。因此,在Mockito中,当您定义一个mock时,您可以如下所示为每个调用指定返回值:

when(myMock.someMethod(arg1, arg2)).thenReturn(returnValue);

当<代码>myMock时。someMethod是用参数调用的,我在测试中没有给它返回值,它只返回null。我想将其配置为立即崩溃,并告诉我,我忘记为一些参数组合定义返回值。

编辑2:有人建议提供一个自定义的defaultAnswer,调用时会抛出异常。不幸的是,这不起作用。即使存在模拟,也会调用默认的answers“answer()方法。以下是一个示例

public class Test {
  public static class Adder {
    public int add(int a, int b) {
      return a + b;
    }
  }

  public static final Answer<Object> THROW_ON_UNDEFINED_ARGS = new Answer<Object>() {
    @Override
    public Object answer(InvocationOnMock invocation) throws Throwable {
      throw new IllegalArgumentException(
          String.format("Calling a mock with undefined arguments: %s %s",
              invocation.getMethod(),
              Arrays.toString(invocation.getArguments())));
    }
  };

  public static void main(String[] args) {
    Adder adderMock = mock(Adder.class, THROW_ON_UNDEFINED_ARGS);
    when(adderMock.add(2, 3)).thenReturn(5);
    System.out.println(adderMock.add(2, 3));
  }
}

即使定义了adderMock.add(2,3),也会引发异常。

共有3个答案

阴高寒
2023-03-14

只需指出另一种可以做到这一点的方法,使用然后回答

when(myMock.someMethod(anyString(), anyString())).
            thenAnswer(new Answer<String>() {
               @Override
               public String answer(InvocationOnMock invocation) throws Throwable {
                  Object[] args = invocation.getArguments();
                  String arg1 = (String) args[0];
                  String arg2 = (String) args[1];

                  if ("arg1".equals(arg1) && "arg2".equals(arg2)) return "someValue";

                  throw new Exception();
               }
            });

      myMock.someMethod("arg1", "arg2"); // Returns "someValue"
      myMock.someMethod("xxx", "yyy");   // Throws Exception

希望有帮助。

蒲曦
2023-03-14

首先,有点“好工程”的咕哝——你为什么要这样做?Mockito尝试“提升”BDD风格-您设置(模拟)调用,执行代码并验证交互是否完全符合预期,而不是“它没有调用任何其他内容”-您是否尝试执行查找无关调用中描述的操作?一般来说,如果我想模拟所有的情况,但有一个-这让我问自己,我的测试是否真的可以。

无论如何,请转到主题:)

在Mockito中,可以使用不同的值定义多个,如

class Foo {
   public String bar(int a) {
       return "bar = " + a;
   }
}

Mockito.when(task.bar(Matchers.anyInt())).thenReturn("L")
Mockito.when(task.bar(3)).thenThrow(new IllegalAccessError())

task.bar(4); // returns "L" 
task.bar(3); //throws IllegalAccessError

请注意,whens的顺序很重要。规则按相反的顺序处理(或者替代实际的匹配器)。在我的代码中,我们首先模拟anyInt,然后模拟3,这很有效。如果将其反转,则对bar()的两个调用都将返回“L”。

沈乐邦
2023-03-14

您可以在mock的构造中提供一个默认答案,该答案总是引发异常。那么每一个被打断的电话都会像往常一样。这些路径之外的所有内容都将引发异常。类似这样:

final String arg = "some arg";
Collection<Object> object = mock(Collection.class, new Answer<Object>() {
    @Override
    public Object answer(InvocationOnMock invocation) throws Throwable {
        throw new IllegalArgumentException("You cannot invoke " + invocation.getMethod() +
                                    " with " + Arrays.toString(invocation.getArguments()));
    }
});
doReturn(true).when(object).add(arg);

object.add(arg); // Goes ok
object.add("azertyuiop"); // Throws the exception
 类似资料:
  • 我正在使用Mockito来模拟服务层的方法。 试图嘲笑以下代码行 为了嘲笑我正在使用的这个 但问题是当代码到达行

  • 假设我有以下代码行, 我的代码为: 现在发生的情况是,当编译器到达}catch(final SQLException se){时,它没有转到它的catch主体,只是脱离了,不知道为什么吗?

  • 我想模拟特定参数的方法调用并为其他参数调用真正的方法。我有: 这样,我就得到了folderDAO的模拟结果。getFoldersHierarchy(EHierarchyType.CLIENT\u DOC)但是当我尝试用任何其他参数调用它时,我得到了NullPointerException 那么,我做错了什么,或者应该如何只针对特定参数存根方法调用呢? junit-jupiter api: 5.4.

  • 已编辑:我对render方法有一个自定义异常,当我抛出它时(例如从控制器中)会调用该异常,但当我在View composer中抛出它时,不会调用该异常。 所以当我这样做的时候 并将dd()置于异常呈现方法 我没有得到任何结果。 如果我直接记录我的异常,会发现首先抛出的是CustomException,然后会看到ErrorException。 我找到了一个扔它的地方。 \照明\查看\引擎\Compi

  • 当方法运行时,我希望抛出一个异常(在测试时)。我能做的事情很少: 存根(mock.someMethod(“某些参数”)).ToThrow(new RuntimeException()); 当(mock.someMethod(“某些参数”)).thenThrow(new RuntimeException()) 放弃..... 通常我会创建一个spy对象来调用spied方法。使用stubbing我可以

  • 我在类中有一个签名为的方法。 我有一个调用方法的代码块: 如果我想测试databaseService.save(user)没有被调用,那么我如何用Mockito(3.3.3版)来做呢?