使用mockito设置变量值

时间:2016-11-01 11:56:21

标签: unit-testing mockito

我有:

    SomeClass a = spy(SomeClass.class)

SomeClassprivate int myValue

我想将myVlaue设置为3。

我怎么能用Mockito做到这一点?

(如果不能与Mockito合作,那么我的下一个最佳选择是什么,最好不要丢弃使用Mockito的代码)。

注意:

  • 不建议模仿getMyValue(),我已经知道我可以做到。
  • 不建议添加setMyValue(int newMyValue),我不想要它。

4 个答案:

答案 0 :(得分:2)

到目前为止,我提出的最佳选择是反思:

Field myVarField = SomeClass.class.getDeclaredField("myVarField");
myVarField.setAccessible(true);
myVarField.set(someClass,3);

答案 1 :(得分:1)

反思是正确的答案。除了@InjectMocksthe recently removed internal class Whitebox之外,Mockito根本不关心字段,因此您需要自己处理字段访问或在您的间谍上调用setter。

至于理由,我还没有见过,但要记住Mockito的作用:它提供工具和简洁的语法来记录和验证交互方法调用,更具体地说 - 通过内部创建动态子类(代理) )覆盖所有方法。对于字段,没有任何内容可以记录或验证,因为JVM只设置了值;使用字段将有点超出Mockito的范围,并介绍了许多关于哪些字段可以更改的警告(私有?静态?最终?)以及您可以用它们做什么(不是存根或验证多个交互)

虽然Mockito并没有明确建议使用getter,但它们是您可以覆盖/跟踪状态访问的少数几个接口之一,所以有一些东西可以说是在整个Java中使用它们进行封装&# 39;那个缘故。如果你不能设置和读取这样的值:

mockitoMockWithFields.fieldA = 42;
return mockitoMockWithFields.fieldB;

然后你要找Mockito做的就是打败封装或终结;即使对于方法来说,Mockito也不能本地化,所以你自己或者使用不同的库来打败他们可能是非常合理的。

答案 2 :(得分:0)

您的测试中a到底是什么?

1)如果a依赖项

您不应该在其上强制使用内部状态,而应将模拟配置为在某个调用中返回所需的值,例如Mockito.doReturn("my current value is: 3").when(a).getText()

其背后的基本思想是,单元测试应独立于其他单元的实现(因此也应独立于那些实现中的缺陷)。操作依赖项的内部状态会导致您的测试与另一个单元紧密耦合。结果将是一个复杂且难以测试的场景。

2)如果a是您的受测试的系统

您可以提供注入myValue的选项,例如包私有方法setMyValue(final int value)。一个经典的示例是将时间戳提供程序插入被测系统(例如Supplier<LocalDateTime>)中,以注入用于测试的修复时间戳(测试无法知道某个操作使用了哪个时间戳,因此它需要为定义明确的测试方案注入修复时间戳记)。这种用于单元测试的实用方法应该是私有的。

旁注: 单元测试必须简单,易于阅读和理解。不要称呼模拟“ a”,请使用适合其性质的名称!在所有测试中,我也经常将被测系统称为“ sut”。因此,很容易区分正在测试的内容和依赖项。

答案 3 :(得分:-1)

尝试以下代码,

use org.springframework.test.util.ReflectionTestUtils
ReflectionTestUtils.setField(yourClass, "yourFieldName", yourFieldValue);