在Mockito 2.2中,我用什么代替Whitebox来设置字段?

使用Mockito 1.9.x时,我一直在使用Whitebox将字段值设置为“注入”模拟。Se示例如下:

@Before

public void setUp() {

eventHandler = new ProcessEventHandler();

securityService = new SecurityServiceMock();

registrationService = mock(RegistrationService.class);

Whitebox.setInternalState(eventHandler, "registrationService", registrationService);

Whitebox.setInternalState(eventHandler, "securityService", securityService);

}

我真的很喜欢这种方法,但是现在我尝试升级到Mockito

2.2.7我发现(或者更确切地说,我的IDE并告诉我很多次),在Mockito中不再找到Whitebox。

我找到了一个替代方法,可以替代它,就是这样org.powermock.reflect.Whitebox的问题是,我得到了另一个依赖项(Powermock),只是为了使用Whitebox。

Powermock也有一个名为的类Whitebox,但不幸的是,它看起来无法与Mockito 2.2.x

在Mockito中,有什么好的替代方法可以用来手动“注入”字段,而现在这些替代方法Whitebox不再可用了?


回答:

我在评论中写了@JeffBowman的帖子。简而言之,我选择复制并使用WhiteBox的代码,因为在大多数测试用例中都使用了它,并且该类不依赖于其他类。这是解决此问题的最快途径。

@bcody建议的解决方案是更好的选择,如果您使用的是spring,则它不会增加任何代码供您维护。我知道这些信息了:(

回答:

请注意,Whitebox它始终在org.mockito.internal包装中。除了增加主版本号外,还可以internal指定该软件包可能会发生重大更改。

如果您确实希望在测试中设置否则无法访问的字段,则可以采用与之相同的方法setInternalState,即仅在层次结构中标识该字段,对其进行调用setAccessible,然后进行设置。完整代码在grepcode上。您还可以检查多种其他方法来设置测试中的不可访问状态。

public static void setInternalState(Object target, String field, Object value) {

Class<?> c = target.getClass();

try {

Field f = getFieldFromHierarchy(c, field); // Checks superclasses.

f.setAccessible(true);

f.set(target, value);

} catch (Exception e) {

throw new RuntimeException(

"Unable to set internal state on a private field. [...]", e);

}

}

在这种情况下,我的一般建议是 停止使用这些工具

:Java的四个封装级别(公共,受保护,程序包,私有)不一定足以表达您要表达的保护程度,并且在尝试进行反思时,添加记录良好的初始化方法或构造函数重写来覆盖依赖关系通常要容易得多。如果将测试与所测试的类放在同一Java包中,则通常甚至可以将字段或方法/构造函数包设为私有,这也是设置并行源文件夹srctests(表示)两个文件夹的好理由同一Java包的一半。

尽管有些人将这种额外的方法或构造函数视为“ API污染”,但我认为它是按照类中最重要的使用者之一的要求(即 自己的测试)进行

编码。如果您需要原始的外部接口,则可以轻松地单独定义一个接口,以便隐藏所需的任何细节。但是,您可能会发现自己 喜欢

将任何实际或模拟的实现直接注入到您现在更灵活的组件中的能力,此时,您可能希望研究依赖项注入模式或框架。

以上是 在Mockito 2.2中,我用什么代替Whitebox来设置字段? 的全部内容, 来源链接: utcz.com/qa/416382.html

回到顶部