2016-09-14 2 views
1

Я хочу высмеять поведение, возвращая различные объекты CloseableHttpResponse на основе URL-адресов. Я ищу URL1 Я хочу сообщить 302 и url2 Я хочу дать 200 ok отклик. Метод в этом тесте принимает url как входной сигнал и создает объект запроса HttpGet и делает что-то с httpresponse объектом. Но я не могу сопоставить аргумент HttpGet. Есть ли способ проверить этот метод. Постскриптум httpClient - также макет объекта. Следующий код не работает, так как ожидание не может издеваться над новым HttpGet(Url).Объект совпадения HttpGet, который создается внутри метода под тестом

CloseableHttpResponse httpResponse = mock(CloseableHttpResponse.class); 
    when(httpClient.execute(new HttpGet(URL1))).thenReturn(httpResponse); 
    when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("1.1",0,0),HttpStatus.SC_MOVED_PERMANENTLY,"")); 
    when(httpResponse.getHeaders(HttpHeaders.LOCATION)).thenReturn(new Header[]{new BasicHeader(HttpHeaders.LOCATION, URL2)}); 

    CloseableHttpResponse httpResponse1 = mock(CloseableHttpResponse.class); 
    when(httpClient.execute(new HttpGet(URL2))).thenReturn(httpResponse1); 
    when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("1.1",0,0),HttpStatus.SC_OK,"")); 
    when(httpResponse.getHeaders(HttpHeaders.CONTENT_LENGTH)).thenReturn(new Header[]{new BasicHeader(HttpHeaders.CONTENT_LENGTH, "0")}); 

Заранее спасибо.

+0

Вы не можете «подделывать» или «сопоставлять» объект HttpGet? Ваш вопрос не совсем ясен, но я думаю, что вы ищете это: https://mrtnrbrts.wordpress.com/2012/09/12/custom-matchers-with-mockito/ – Taylor

+0

Привет Тейлор Спасибо. Матч будет правильным словом. отредактирован :). Можете ли вы подробнее рассказать о том, как ссылка, которую вы предоставили, решает мою проблему. –

+1

Я бы серьезно предложил переместить эти тесты в WireMock. –

ответ

3

Вам нужен пользовательский аргумент совпадение.

Так что-то вроде этого в тестовом классе:

static class HttpGetMatcher extends ArgumentMatcher<HttpGet> { 

    private final URL expected; 

    //Match by URL 
    public HttpGetMatcher(URL expected) { 
     this.expected = expected; 
    } 

    @Override 
    public boolean matches(Object actual) { 
     // could improve with null checks 
     return ((HttpGet) actual).getURI().equals(expected); 
    } 

    @Override 
    public void describeTo(Description description) { 
     description.appendText(expected == null ? null : expected.toString()); 
    } 
} 

private static HttpGet aHttpGetWithUriMatching(URI expected){ 
    return argThat(new HttpGetMatcher(expected)); 
} 

выше может также находиться в некоторых тестовых Utils класса, если вам нужно в нескольких тестовых классов. Тогда в этом случае метод aHttpGetWithUriMatching должен быть общедоступным.

А потом в методе испытания:

CloseableHttpResponse httpResponse = mock(CloseableHttpResponse.class); 
when(httpClient.execute(aHttpGetWithUriMatching(URL1))).thenReturn(httpResponse); 
when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("1.1",0,0),HttpStatus.SC_MOVED_PERMANENTLY,"")); 
when(httpResponse.getHeaders(HttpHeaders.LOCATION)).thenReturn(new Header[]{new BasicHeader(HttpHeaders.LOCATION, URL2)}); 

Надеется, что это помогает.

+1

Он работает правильно с одним матчи. Хотя я застрял во втором выпуске. Когда я пытаюсь установить ожидание для URL2, он начинает давать мне исключение с нулевым указателем. Решено на этой странице http://stackoverflow.com/questions/13846837/using-multiple-argumentmatchers-on-the-same-mock?rq=1 –