我正在测试某个班级.该类在内部实例化一个“GetMethod”对象,该对象被传递给“HttpClient”对象,该对象被注入到测试类中.
我正在嘲笑“HttpClient”类,但我还需要修改“GetMethod”类的一个方法的行为.我正在玩ArgumentCaptor,但我似乎无法在“when”调用中获取实例化对象.
例:
- HttpClient mockHttpClient = mock(HttpClient.class);
- ArgumentCaptor<GetMethod> getMethod = ArgumentCaptor.forClass(GetMethod.class);
- when(mockHttpClient.executeMethod(getMethod.capture())).thenReturn(HttpStatus.SC_OK);
- when(getMethod.getValue().getResponseBodyAsStream()).thenReturn(new FileInputStream(source));
响应:
- org.mockito.exceptions.base.MockitoException:
- No argument value was captured!
- You might have forgotten to use argument.capture() in verify()...
- ...or you used capture() in stubbing but stubbed method was not called.
- Be aware that it is recommended to use capture() only with verify()
解决方法
你不能在getMethod上使用,因为getMethod不是mock.它仍然是您的班级创建的真实对象.
ArgumentCaptor有着截然不同的目的.检查section 15 here.
您可以使您的代码更易于测试.通常,创建其他类的新实例的类很难测试.把一些工厂放到这个类来创建get / post方法,然后在test mock中修改这个工厂,并使它成为模拟get / post方法.
- public class YourClass {
- MethodFactory mf;
- public YourClass(MethodFactory mf) {
- this.mf = mf;
- }
- public void handleHttpClient(HttpClient httpClient) {
- httpClient.executeMethod(mf.createMethod());
- //your code here
- }
- }
然后在测试中你可以做到:
- HttpClient mockHttpClient = mock(HttpClient.class);
- when(mockHttpClient.executeMethod(any(GetMethod.class)).thenReturn(HttpStatus.SC_OK);
- MethodFactory factory = mock(MethodFactory.class);
- GetMethod get = mock(GetMethod.class);
- when(factory.createMethod()).thenReturn(get);
- when(get.getResponseBodyAsStream()).thenReturn(new FileInputStream(source));
UPDATE
您还可以尝试一些讨厌的黑客,并通过反射回答和访问GetMethod的私有部分;). (这真是讨厌的黑客)
- when(mockHttpClient.executeMethod(any(GetMethod.class))).thenAnswer(new Answer() {
- Object answer(InvocationOnMock invocation) {
- GetMethod getMethod = (GetMethod) invocation.getArguments()[0];
- Field respStream = HttpMethodBase.class.getDeclaredField("responseStream");
- respStream.setAccessible(true);
- respStream.set(getMethod,new FileInputStream(source));
- return HttpStatus.SC_OK;
- }
- });