我试图模仿arraylist来验证添加方法,但我收到了消息:
FAILED: testInit
Wanted but not invoked:
arrayList.add(<any>);
-> at AsyncRestTemplateAutoConfigurationTest.testInit(AsyncRestTemplateAutoConfigurationTest.java:95)
Actually, there were zero interactions with this mock.
我使用的测试类是:
@Test
public void testInit() throws Exception {
ArrayList<AsyncClientHttpRequestInterceptor> interceptors = Mockito.mock(ArrayList.class);
PowerMockito.whenNew(ArrayList.class).withAnyArguments()
.thenReturn(interceptors);
Mockito.stub(interceptors.add(Mockito.any())).toReturn(true);
asyncRestTemplateAutoConfiguration.init();
Mockito.verify(interceptors).add(Mockito.any());
}
实际测试的代码是:
List<AsyncClientHttpRequestInterceptor> interceptors = new ArrayList<>(interceptors);
interceptors.add(new TracingAsyncRestTemplateInterceptor(tracer));
我已经用
声明了测试类@RunWith(PowerMockRunner.class)
@PrepareForTest(AsyncRestTemplateAutoConfiguration.class)
AsyncRestTemplateAutoConfiguration
是哪个类,我用来测试。谁能告诉我我失踪了什么?
答案 0 :(得分:3)
您的单元测试应验证公共可观察行为 返回值和与依赖项的通信(这不仅仅意味着仅测试{ {1}}方法)。
您的生产代码使用public
来存储您的数据是实施细节您不想测试,因为它可能会在不更改单位一般行为的情况下进行更改,在哪种情况下,你的单位测试不应该失败。
答案 1 :(得分:3)
不要开始学习如何使用PowerMockito进行单元测试 - 它会给你不良习惯。
相反,请考虑仔细阅读documentation for Mockito,您将看到如何构建类以便进行更好的测试。
理想情况下,您的课程应该是这样的,您不需要PowerMockito来测试它们,您可以只依靠普通的Mockito。
如果您能够使用Mockito进行优雅而简单的测试,那么您将掌握单元测试的基本概念。
您可以从学习如何通过类的构造函数注入依赖项开始,这些构造函数可以与模拟的测试双重交换,从而可以验证哪些行为。
另一点需要注意的是,根据另一个答案,被测系统中的内部ArrayList
是一个实现细节。除非被测系统的消费者能够访问ArrayList
,比如暴露它的方法,否则编写测试没有多大意义。
如果内部ArrayList
的状态从消费者的角度影响了某些内容,那么请尝试针对该内容进行测试,而不是针对内部属性。
祝你在单元测试中获得成功!