質問

私は、特定のクラスをテストしています。このクラスは、内部でテストクラス内に注入されます「のHttpClient」オブジェクトに渡される「GetMethod」オブジェクトをインスタンス化されます。

私は「HttpClientを」クラスをからかうんだけど、私も「GetMethod」クラスの1つの方法の動作を変更する必要があります。私はArgumentCaptorと一緒に遊んだが、私は「いつ」呼び出しでインスタンス化されたオブジェクトのホールドを取得することができていないようです。

例:

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()
役に立ちましたか?

解決 2

[OK]を、これは私がそれを解決してきた方法です。少しは畳み込まれたが、他の方法を見つけることができませんでした。

テストクラスで、

private GetMethod getMethod;

public void testMethod() {
    when(mockHttpClient.executeMethod(any(GetMethod.class))).thenAnswer(new ExecuteMethodAnswer());
    //Execute your tested method here.
    //Acces the getMethod here, assert stuff against it.  
}

private void setResponseStream(HttpMethodBase httpMethod, InputStream inputStream) throws NoSuchFieldException, IllegalAccessException {
    Field privateResponseStream = HttpMethodBase.class.getDeclaredField("responseStream");
    privateResponseStream.setAccessible(true);
    privateResponseStream.set(httpMethod, inputStream);
}

private class ExecuteMethodAnswer implements Answer {
    public Object answer(InvocationOnMock invocation) throws FileNotFoundException,
                                                             NoSuchFieldException, IllegalAccessException {
        getMethod = (GetMethod) invocation.getArguments()[0];
        setResponseStream(getMethod, new FileInputStream(source));
        return HttpStatus.SC_OK;
    }
}

他のヒント

getMethodはモックではないので、

あなたは、getMethodにwhenを使用傾けます。それはまだあなたのクラスによって作成された実際のオブジェクトです。

ArgumentCaptorは全く異なる目的を持っています。ここを部15を確認してください。

あなたはあなたのコードがより多くのテスト可能にすることができます。一般的に、他のクラスの新しいインスタンスを作成しているクラスをテストするのは困難です。 get /ポストメソッドを作成するために、このクラスにいくつかの工場を置き、その後のテストで、この工場をあざけり、それが取得モック/ポストメソッドを作成します。

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

また、いくつかの厄介なハック、およびAnswerを試してみて、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;
  }
});
scroll top