【问题标题】:How to validate the return value when calling a mocked object's method调用模拟对象的方法时如何验证返回值
【发布时间】:2013-09-20 00:13:01
【问题描述】:

使用 Mockito,有没有办法对对象进行 spy() 并验证对象是否使用指定的参数被调用了给定的 # 次,并且它是否为这些调用返回了预期值?

我想做如下的事情:

class HatesTwos {
  boolean hates(int val) {
    return val == 2;
  }
}

HatesTwos hater = spy(new HatesTwos());
hater.hates(1);
assertFalse(verify(hater, times(1)).hates(1));

reset(hater);
hater.hates(2);
assertTrue(verify(hater, times(1)).hates(2));

【问题讨论】:

  • 听起来你想同时测试两个类。您正在测试您正在监视的类,因为您想测试它是否返回预期值。您正在测试调用您正在监视的类的类,因为您想测试传递了哪些参数。对我来说,这似乎是两个独立的测试,我强烈建议不要尝试将它们合二为一。
  • 但是如果我有一个类调用它自己的方法(这是合理的行为)怎么办?然后测试 MyClass.funcThatGetsCalledByAnotherMyClassFunc() 返回一个特定的值并且它被调用一定的次数都是有效的。
  • 它们真的都有效吗?专注于测试你的类的行为是否正确,而不是它的实现是你认为的那样。当你测试方法 A 时,你应该只关心方法 A 的输出,而不是它是否调用方法 B 以及它传递了什么参数。如果你也想测试方法 B,当然可以。
  • @DavidWallace 我不明白为什么要验证方法的输出和行为没有意义。无论哪种方式,您对我的原始帖子有任何见解吗?
  • @ChrisMorris 3 年过去了:您现在可能是一名测试大师。您现在对上述cmets有什么见解吗?作为一个测试新手,我发现“我们只测试功能接口”的想法并不令人满意:我认为我们可能倾向于使用“测试接口”这样的东西,它可能是“功能接口”的超集,并且所以可能会调用自己的方法...

标签: java mocking mockito spy


【解决方案1】:

您可以使用Answer 接口来捕获真正的响应。

public class ResultCaptor<T> implements Answer {
    private T result = null;
    public T getResult() {
        return result;
    }

    @Override
    public T answer(InvocationOnMock invocationOnMock) throws Throwable {
        result = (T) invocationOnMock.callRealMethod();
        return result;
    }
}

预期用途:

class HatesTwos {
    boolean hates(int val) {
        return val == 2;
    }
}

HatesTwos hater = spy(new HatesTwos());

// let's capture the return values from hater.hates(int)
ResultCaptor<Boolean> hateResultCaptor = new ResultCaptor<>();
doAnswer(hateResultCaptor).when(hater).hates(anyInt());

hater.hates(1);
verify(hater, times(1)).hates(1);
assertFalse(hateResultCaptor.getResult());

reset(hater);

hater.hates(2);
verify(hater, times(1)).hates(2);
assertTrue(hateResultCaptor.getResult());

【讨论】:

  • 这对我不起作用...在我的某些代码中,doAnswer 方法调用不会导致对ResultCaptor.answer 的调用。然后,当我将您的代码逐字复制到实验类时,运行main 中的第二位,调用answer 后,第一个测试(assertFalse)通过(假)。第二次测试 (assertTrue) 失败,返回 false 而实际上并未调用 answer
  • 啊...但是当我创建 HatesTwo hater2 并摆脱 reset 时它通过了。在(当前)Mockito Javadoc 中,建议不要使用 Mockito.reset()..
猜你喜欢
  • 1970-01-01
  • 2023-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多