it-swarm.com.ru

Как мне издеваться REST обмен шаблонами?

У меня есть сервис, в котором мне нужно запросить информацию у внешнего сервера:

public class SomeService {

    public List<ObjectA> getListofObjectsA() {
        List<ObjectA> objectAList = new ArrayList<ObjectA>();
        ParameterizedTypeReference<List<ObjectA>> typeRef = new ParameterizedTypeReference<List<ObjectA>>() {};
        ResponseEntity<List<ObjectA>> responseEntity = restTemplate.exchange("/objects/get-objectA", HttpMethod.POST, new HttpEntity<>(ObjectAList), typeRef);
        return responseEntity.getBody();
    }
}

Как я могу написать тест JUnit для getListofObjectsA()?

Я пытался с ниже:

@RunWith(MockitoJUnitRunner.class)
public class SomeServiceTest {
    private MockRestServiceServer mockServer;

    @Mock
    private RestTemplate restTemplate;

    @Inject
   private SomeService underTest;

@Before
public void setup() {
    mockServer = MockRestServiceServer.createServer(restTemplate);
    underTest = new SomeService(restTemplate);
    mockServer.expect(requestTo("/objects/get-objectA")).andExpect(method(HttpMethod.POST))
            .andRespond(withSuccess("{json list response}", MediaType.APPLICATION_JSON));
}

    @Test
    public void testGetObjectAList() {
    List<ObjectA> res = underTest.getListofObjectsA();
    Assert.assertEquals(myobjectA, res.get(0));
}

Однако приведенный выше код не работает, он показывает, что responseEntitty является null. Как я могу исправить свой тест, чтобы правильно смоделировать restTemplate.exchange?

17
Akka Jaworek

Вам не нужен объект MockRestServiceServer. Аннотация: @InjectMocks, а не @Inject. Ниже приведен пример кода, который должен работать

@RunWith(MockitoJUnitRunner.class)
public class SomeServiceTest {
    @Mock
    private RestTemplate restTemplate;

    @InjectMocks
    private SomeService underTest;

    @Test
    public void testGetObjectAList() {
        ObjectA myobjectA = new ObjectA();
        //define the entity you want the exchange to return
        ResponseEntity<List<ObjectA>> myEntity = new ResponseEntity<List<ObjectA>>(HttpStatus.ACCEPTED);
        Mockito.when(restTemplate.exchange(
            Matchers.eq("/objects/get-objectA"),
            Matchers.eq(HttpMethod.POST),
            Matchers.<HttpEntity<List<ObjectA>>>any(),
            Matchers.<ParameterizedTypeReference<List<ObjectA>>>any())
        ).thenReturn(myEntity);

        List<ObjectA> res = underTest.getListofObjectsA();
        Assert.assertEquals(myobjectA, res.get(0));
    }
17
Mindaugas
ResponseEntity<String> responseEntity = new ResponseEntity<String>("sampleBodyString", HttpStatus.ACCEPTED);
when(restTemplate.exchange(
                           Matchers.anyString(), 
                           Matchers.any(HttpMethod.class),
                           Matchers.<HttpEntity<?>> any(), 
                           Matchers.<Class<String>> any()
                          )
                         ).thenReturn(responseEntity);
14
Shyam Elakapalli

Это пример с неутешенным ArgumentMatchers class

when(restTemplate.exchange(
                ArgumentMatchers.anyString(),
                ArgumentMatchers.any(HttpMethod.class),
                ArgumentMatchers.any(),
                ArgumentMatchers.<Class<String>>any()))
             .thenReturn(responseEntity);
8
itstata

Для меня я должен был использовать Matchers.any (URI.class) 

Mockito.when(restTemplate.exchange(Matchers.any(URI.class), Matchers.any(HttpMethod.class), Matchers.<HttpEntity<?>> any(), Matchers.<Class<Object>> any())).thenReturn(myEntity);
4
Abbin Varghese

Эта работа на моей стороне.

ResourceBean resourceBean = initResourceBean();
ResponseEntity<ResourceBean> responseEntity  
    = new ResponseEntity<ResourceBean>(resourceBean, HttpStatus.ACCEPTED);
when(restTemplate.exchange(
    Matchers.anyObject(), 
    Matchers.any(HttpMethod.class),
    Matchers.<HttpEntity> any(), 
    Matchers.<Class<ResourceBean>> any())
 ).thenReturn(responseEntity);
2
chendu

Экземпляр RestTemplate должен быть реальным объектом. Это должно работать, если вы создаете реальный экземпляр RestTemplate и делаете его @Spy.

@Spy
private RestTemplate restTemplate = new RestTemplate();
0
Manoj Shrestha

Если вы намерены протестировать службу, не заботясь об остальном вызове, я предлагаю не использовать аннотации в вашем модульном тесте для упрощения теста.

Итак, я предлагаю реорганизовать ваш сервис, чтобы получить шаблон с использованием инъекционного конструктора. Это облегчит тестирование. Пример:

@Service
class SomeService {
    @AutoWired
    SomeService(TestTemplateObjects restTemplateObjects) {
        this.restTemplateObjects = restTemplateObjects;
    }
}

RestTemplate как компонент, который будет вставлен и смоделирован после:

@Component
public class RestTemplateObjects {

    private final RestTemplate restTemplate;

    public RestTemplateObjects () {
        this.restTemplate = new RestTemplate();
        // you can add extra setup the restTemplate here, like errorHandler or converters
    }

    public RestTemplate getRestTemplate() {
        return restTemplate;
    }
}

И тест:

public void test() {

    when(mockedRestTemplateObject.get).thenReturn(mockRestTemplate);

    //mock restTemplate.exchange
    when(mockRestTemplate.exchange(...)).thenReturn(mockedResponseEntity);

    SomeService someService = new SomeService(mockedRestTemplateObject);
    someService.getListofObjectsA();
}

Таким образом, у вас есть прямой доступ к макету шаблона остатка с помощью конструктора SomeService.

0
Dherik

Я реализовал небольшая библиотека это довольно полезно. Он предоставляет ClientHttpRequestFactory, который может получить некоторый контекст. Таким образом, он позволяет пройти через все клиентские уровни, например, проверить, что параметры запроса оцениваются, установить заголовки и проверить, что десериализация работает хорошо.

0
Kier GRAY