Java 如何使用whenNew方法模拟ArrayList类
我正在尝试模拟arraylist以验证add方法,但收到以下消息:Java 如何使用whenNew方法模拟ArrayList类,java,unit-testing,mockito,powermock,Java,Unit Testing,Mockito,Powermock,我正在尝试模拟arraylist以验证add方法,但收到以下消息: FAILED: testInit Wanted but not invoked: arrayList.add(<any>); -> at AsyncRestTemplateAutoConfigurationTest.testInit(AsyncRestTemplateAutoConfigurationTest.java:95) Actually, there were zero interactions wit
FAILED: testInit
Wanted but not invoked:
arrayList.add(<any>);
-> at AsyncRestTemplateAutoConfigurationTest.testInit(AsyncRestTemplateAutoConfigurationTest.java:95)
Actually, there were zero interactions with this mock.
其中
AsyncRestTemplateAutoConfiguration
是我用来测试的类。有人能告诉我我缺少什么吗?您的单元测试应该验证公共可观察行为,即返回值和与依赖项的通信(这不一定意味着只测试公共方法)
生产代码使用ArrayList
存储数据是一个实现细节,您不想测试它,因为它可以在不改变单元常规行为的情况下进行更改,在这种情况下,您的单元测试不应该失败。您的单元测试应该验证公共可观察行为,即返回值和与依赖项的通信(这并不一定意味着只测试公共方法)
生产代码使用ArrayList
存储数据是一个实现细节,您不想测试它,因为它可以在不改变单元一般行为的情况下进行更改,在这种情况下,单元测试应该不会失败。不要开始学习如何使用PowerMockito进行单元测试-这会给您带来坏习惯
而不是仔细考虑通过它工作,你会看到如何构造你的类来进行更好的测试。
理想情况下,您的类不需要PowerMockito来测试它们,您可以只依赖普通的Mockito
如果您能够使用Mockito编写优雅而简单的测试,这将表明您已经掌握了单元测试的基本概念
您可以从学习如何通过类的构造函数注入依赖项开始,该类可以与模拟测试双精度进行交换,在模拟测试双精度上可以验证行为
另一点需要注意的是,根据另一个答案,测试系统中的内部ArrayList
是一个实现细节。除非被测系统的使用者可以通过公开的方法访问ArrayList
,否则编写针对它的测试没有多大意义
如果内部ArrayList
的状态从使用者的角度影响某些内容,则尝试针对该内容编写测试,而不是针对内部属性编写测试
祝您在单元测试之旅中好运 不要开始学习如何使用PowerMockito进行单元测试-这会给你带来坏习惯
而不是仔细考虑通过它工作,你会看到如何构造你的类来进行更好的测试。
理想情况下,您的类不需要PowerMockito来测试它们,您可以只依赖普通的Mockito
如果您能够使用Mockito编写优雅而简单的测试,这将表明您已经掌握了单元测试的基本概念
您可以从学习如何通过类的构造函数注入依赖项开始,该类可以与模拟测试双精度进行交换,在模拟测试双精度上可以验证行为
另一点需要注意的是,根据另一个答案,测试系统中的内部ArrayList
是一个实现细节。除非被测系统的使用者可以通过公开的方法访问ArrayList
,否则编写针对它的测试没有多大意义
如果内部ArrayList
的状态从使用者的角度影响某些内容,则尝试针对该内容编写测试,而不是针对内部属性编写测试
祝您在单元测试之旅中好运 @TimothyTruckle你想把这个值得投票的评论变成答案吗?@DavidDrawson完成了…@TimothyTruckle你想把这个值得投票的评论变成答案吗?@DavidDrawson完成了。。。
@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)