如何使Mockito模拟游戏依次执行不同的动作? [英] How can I make a Mockito mock perform different actions in sequence?

查看:106
本文介绍了如何使Mockito模拟游戏依次执行不同的动作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码:

  ObjectMapper mapper = Mockito.mock(ObjectMapper.class);
  Mockito.doThrow(new IOException()).when(mapper).writeValue((OutputStream) Matchers.anyObject(), Matchers.anyObject());
  Mockito.doNothing().when(mapper).writeValue((OutputStream) Matchers.anyObject(), Matchers.anyObject());

  try {
      mapper.writeValue(new ByteArrayOutputStream(), new Object());
  } catch (Exception e) {
      System.out.println("EXCEPTION");
  }

  try {
      mapper.writeValue(new ByteArrayOutputStream(), new Object());
  } catch (Exception e) {
      System.out.println("EXCEPTION");
  }

预期输出是

例外

对吗?

但是我什么也没得到

如果我随后在doNothing之后做出doThrow

If I then make the doThrow after the doNothing I get

EXCEPTION
例外

EXCEPTION
EXCEPTION

所以看起来好像是最后一个模拟了……我想它会按照模拟的注册顺序接受模拟?

So It looks like it is the last mock that is the one that is taken... I thought it would take the mocks in the order they're registered?

我希望产生一个模拟,第一次抛出异常,第二次正常完成...

I'm looking to produce a mock throws the exception first time and completes normally the second time...

推荐答案

Mockito可以对具有相同参数的连续行为进行存根-永远重复最后一条指令-但它们都必须属于同一链"的一部分.否则,Mockito会有效地认为您改变了主意并覆盖了以前模拟的行为,如果您已经在setUp@Before方法中建立了良好的默认值并想在特定的方法中覆盖它们,那么这并不是一个坏功能.测试用例.

Mockito can stub consecutive behavior with the same parameters—forever repeating the final instruction—but they all have to be part of the same "chain". Otherwise Mockito effectively thinks you've changed your mind and overwrites your previously-mocked behavior, which isn't a bad feature if you've established good defaults in a setUp or @Before method and want to override them in a specific test case.

下一步将发生哪些Mockito动作"的一般规则:将选择与所有参数匹配的最近定义的链.在该链中,每个动作将发生一次(如果给出多个thenReturn值,如thenReturn(1, 2, 3)一样,则计数多个),然后最后一个动作将永远重复.

The general rules for "which Mockito action will happen next": The most-recently-defined chain that matches all arguments will be selected. Within the chain, each action will happen once (counting multiple thenReturn values if given like thenReturn(1, 2, 3)), and then the last action will be repeated forever.

// doVerb syntax, for void methods and some spies
Mockito.doThrow(new IOException())
    .doNothing()
    .when(mapper).writeValue(
        (OutputStream) Matchers.anyObject(), Matchers.anyObject());

这等效于更常见的when语法中的链式thenVerb语句,对于您的void方法,此处已正确避免了使用该语法:

This is the equivalent of chained thenVerb statements in the more-common when syntax, which you correctly avoided here for your void method:

// when/thenVerb syntax, to mock methods with return values
when(mapper.writeValue(
        (OutputStream) Matchers.anyObject(), Matchers.anyObject())
    .thenThrow(new IOException())
    .thenReturn(someValue);

请注意,您可以对Mockito.doThrowMatchers.*使用静态导入,并切换到any(OutputStream.class)而不是(OutputStream) anyObject(),然后结束:

Note that you can use static imports for Mockito.doThrow and Matchers.*, and switch to any(OutputStream.class) instead of (OutputStream) anyObject(), and wind up with this:

// doVerb syntax with static imports
doThrow(new IOException())
    .doNothing()
    .when(mapper).writeValue(any(OutputStream.class), anyObject());

请参见 Mockito关于Stubber的文档有关可以链接的命令的完整列表.

See Mockito's documentation for Stubber for a full list of commands you can chain.

这篇关于如何使Mockito模拟游戏依次执行不同的动作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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