【问题标题】:Mockito: call a stub methodMockito:调用存根方法
【发布时间】:2018-07-26 14:09:29
【问题描述】:

我非常熟悉脚本语言中的模拟。在我使用的大多数语言中,都有一个模拟框架允许您调用假函数。例如,在 JavaScript 中,您将使用 sinon 并调用 callsFake,然后传入一个函数:

var sandbox = sinon.createSandbox();
sandbox.stub(myObject, 'some_method').callsFake(() => {
    //do stuff
});

在 Perl 中,您可以使用 Test::MockModule->mock:

my $mockedModule = Test::MockModule->new('Some::Module');
$mockedModule->mock('someMethod', sub {
    #Do stuff
});

在 Java 中可以做到这一点吗?我在 Java 中能做的最好的事情是使用 Mockito 通过调用 when(mock(MyClass.class).method()).thenReturn("foo"); 返回一个固定值。但是,当调用MyClass.method() 时,它总是返回"foo",并且什么也不做。我想知道是否可以改为告诉 Mockito 调用假方法而不是调用真实方法。

这在 Mockito 或其他一些 Java 模拟框架中是否可行。

【问题讨论】:

  • 也许只是创建一个扩展您要模拟的类的类可以工作?
  • 不确定我是否在此处关注您的问题。您不是在测试模拟,而是在测试使用模拟做一些有价值的事情的类。你不希望你的被测类调用 realClass.method(),而是 mockedClass.method()。最终,您想知道每个模拟上的正确方法被调用并返回预期结果,但这是为了测试被测类。
  • @MichaelPeacock 我使用其他语言的示例添加了一些说明

标签: java unit-testing mocking mockito


【解决方案1】:

一个选项是创建一个类,它扩展该类并覆盖您不希望在测试中执行的行为。

另一个选项是这样的:

when(mockedClass.method()).thenAnswer(new Answer() {
    private int count = 0;
    List<String> values = asList("a", "b")
    public Object answer(InvocationOnMock invocation) {
        return values.get(count++)
    }
});

但它可能会导致难以阅读和测试中的极端复杂性。

【讨论】:

  • thenX 方法可能不像你想的那样工作。他们都在真实方法中运行代码,然后返回或回答您何时模拟的任何内容。您必须使用 doX 方法来完全覆盖真实方法,但不建议这样做,因为 doX 方法没有类型检查,通常谨慎使用 doX 模拟。
【解决方案2】:

看看AdditionalAnswers#answer(...),例如:

doAnswer(AdditionalAnswers.answer((a, b) -> a.equals(b))))
    .when(mock).execute(anyString(), anyString());

还有delegatesTo,可能有点用处。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-19
    • 1970-01-01
    • 2011-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多