2015-05-15 4 views
0

У меня есть тестовый случай:EasyMock называет реальный метод

TestClient

@RunWith(EasyMockRunner.class) 
public class TestClient extends EasyMockSupport { 

    @TestSubject 
    private final IClient client = new Client(); 

    @Mock 
    private HttpClient httpClient; 

    @Mock 
    private HttpUriRequest request; 
    @Mock 
    private HttpResponse response; 

    @Test 
    public void testExecute() throws ClientProtocolException, IOException { 
     expect(httpClient.execute(request)).andReturn(response); 
     replayAll(); 
     httpClient.execute(request); 
     client.execute(request); 
     verifyAll(); 
    } 
} 

Client

public class Client implements IClient { 

    private final HttpClient httpClient; 

    public Client() { 
     httpClient = createDefaultClient(); 
    } 

    private HttpClient createDefaultClient() { 
     return HttpClientBuilder.create() 
       .build(); 
    } 

    @Override 
    public HttpResponse execute(final HttpUriRequest request) 
      throws IOException { 
     return httpClient.execute(request); 
    } 

} 

Когда я запускаю его я получаю эту ошибку:

Unexpected method call HttpUriRequest.getURI() 

Обычно созданный не будет вызывать этот метод.

Почему я получаю эту ошибку? Почему это требует от меня определения результата для метода getURI?

ответ

2

Вы должны удалить final из

private final HttpClient httpClient; 

В противном случае EasyMock не может перезаписать httpClient с его собственным Передразнивало экземпляр. Конечно, еще лучше было бы использовать инъекцию зависимостей, но это касается вашей реальной проблемы.

Вы canreflection как workaround; но дорогой мне нет ...


Оригинальный ответ:

Проводка полного стека, и соответствующие части Client класса поможет нам отладить это с вами. Вы упомянули, что:

in client.execute(request) I do httpClient.execute(request) .

Но (по крайней мере в коде вы опубликовали) нигде не client получить ссылку на издевались httpClient инстанции. Может ли ваш класс Client построить собственный экземпляр HttpClient и делать запросы от , что вместо вашего макета?

Если да, то ваш Client должен следовать шаблону dependency injection и передать в качестве примера HttpClient при строительстве, а не конструировать его внутри.

Другая возможность заключается в том, что ваш метод Client.execute() звонит request.getURI() в какой-то момент, в этом случае вам просто нужно expect() вызов request.getURI().

+0

. Подчеркнутый «httpClient» будет инъецирован EasyMock (поэтому я использую аннотацию «TestSubject»). Я согласен, что это не видно, если мы не знаем рамки. – Hunsu

+0

@ user230137, пожалуйста, укажите ваш код «Клиент», чтобы мы могли видеть, что он делает. Если вы вызываете 'новый HttpClient()' в любом месте 'Client', который будет использоваться, даже если EasyMock вводит. – dimo414

+0

Я добавил код клиента. При удалении финала он работает, но, возможно, есть решение. – Hunsu

0

Я подозреваю, что внутри метода client.execute(request) есть оператор request.getURI() (или глубоко погруженный в вызываемые методы). Easy Mock должен знать ответ, который нужно дать при вызове этого метода.

+0

в 'client.execute (request)' I do 'httpClient.execute (request)'.Почему EasyMock должен знать ответ для метода getURI? Я создал математическое ожидание метода. Это не вопрос насмешки? – Hunsu

+0

@ user230137 это поможет, если вы разместите содержимое 'Client.execute()'; иначе мы можем только предполагать. – dimo414

0

Я подозреваю, что проблема заключается в звонке httpClient.execute(request);. Попробуйте удалить его. Вы уже настроили ожидание для httpClient через expect(httpClient.execute(request)).andReturn(response);.

@Test 
public void testExecute() throws ClientProtocolException, IOException { 
    expect(httpClient.execute(request)).andReturn(response); 
    replayAll(); 
    client.execute(request); 
    verifyAll(); 
} 
+0

Нет, это не так. EasyMock не смог ввести мой макет, так как поле окончательное, но не выполнено. – Hunsu

Смежные вопросы