JUnit Mock внешний вызов rest через restTemplate - PullRequest
0 голосов
/ 07 мая 2020

Я пытаюсь написать интеграционный тест, в котором у меня возникает проблема с издевательством над остальным вызовом, который вызывает внешний сервер с помощью JUnit. Я добавил @ Mock и @ InjectMock в сервис

Сервис выглядит так.

@Service
public class BoundaryDeltaService {
    private BoundaryDelta getBoundaryDeltaUsingApp() {
       List<BoundaryValueInfo> infoFromSource = Arrays.asList(serviceAdapter.readInfoFromApiUsingApp(boundarySet, app, loginUserInfo));
      return  getBoundaryDeltacompareCurrentBoundaryValuesWithSource(boundarySet, infoFromSource );
    }
}

Есть еще один сервис с restTemplate call

@Service
public class ServiceAdapter {
    public BoundaryValueInfo[] readInfoFromApiUsingApp(){
        String loginToken = systemUserLoginService.getSystemUserTokenManual(app, loginUserInfo);
        restTemplate = createRestTemplate(boundarySet);
        HttpHeaders headers = new HttpHeaders() {{
          String authHeader = "Bearer " + loginToken;
          set( "Authorization", authHeader );
        }};

        HttpEntity<String> request = new HttpEntity<String>(headers);
        ResponseEntity<BoundaryValueInfo[]> answerFromApi = restTemplate.exchange(boundarySet.getApiUri(), HttpMethod.GET, request,  BoundaryValueInfo[].class);
        return getResponseFromApi(answerFromApi);
    }
}

И это тестовый сценарий

@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles({"aws", "local"})
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = FlywayConfig.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
public class BoundaryValueDeltaControllerTest {

    private static final String API_V1 = "/api/v1/";

    @Autowired
    TestRestTemplate testRestTemplate;

    @Autowired
    private BoundaryDeltaService boundaryDeltaService;

    @Autowired
    private DomainBuilder domainBuilder;

    @Autowired
    private AppBuilder appBuilder;

    @Autowired
    private AppAdminBuilder appAdminBuilder;

    @Autowired
    private BoundaryValueBuilder boundaryValueBuilder;

    @Autowired
    private BoundarySetBuilder boundarySetBuilder;

    @MockBean
    private LoginUserProvider loginUserProvider;
    @MockBean
    private LoginTokenService loginTokenService;
    @InjectMocks
    private BoundaryServiceAdapter boundaryServiceAdapter;

    @Mock
    RestTemplate restTemplate;

    @LocalServerPort
    private int port;

    Domain domain;
    App app;
    BoundarySet boundarySet;
    BoundaryValue boundaryValue;
    LoginUserInfo loggedInUser;

    @Before
    public void setUp() {
        clear();
        domain = domainBuilder.persist();
        app = appBuilder.persist(domain);
        boundarySet =  boundarySetBuilder.persist(domain);
        boundaryValue = boundaryValueBuilder.persist(boundarySet);
    }

    @After
    public void tearDown() {
        clear();
    }

    @BeforeClass
    public static void setupTestEnv() {
        // https://github.com/localstack/localstack/issues/592
    }

    @Test
    public void updateBoundaryValuesFromApi() {
        aLoggedInUser(domain.getAuthor().getUsername());
        appAdminBuilder.persist(app, domain.getAuthor());
        ResponseEntity<BoundaryValueInfo[]> answerFromApi = getBoundaryValueInfos();

        HttpHeaders headers = new HttpHeaders() {{
            String authHeader = "Bearer 1234";
            set( "Authorization", authHeader );
        }};

        HttpEntity<String> request = new HttpEntity<>(headers);
        //when(restTemplate.exchange(boundarySet.getApiUri(), HttpMethod.GET, request,  BoundaryValueInfo[].class)).thenReturn(answerFromApi);

        when(restTemplate.exchange(ArgumentMatchers.anyString(),
                ArgumentMatchers.any(HttpMethod.class),
                ArgumentMatchers.any(),
                ArgumentMatchers.<Class<BoundaryValueInfo[]>>any())
        ).thenReturn(answerFromApi);

        String url = url(API_V1 + "domains/" + domain.getName() + "/boundarysets/" + boundarySet.getBoundarySetName() + "/app/" + app.getName()+ "/updatefromapi/");
        ResponseEntity<String> response = testRestTemplate.exchange(url,HttpMethod.GET, null, String.class);

        assertEquals(HttpStatus.OK, response.getStatusCode());
    }
}

Я вызываю контроллер с api, и оттуда он переходит в вышеуказанные службы, которые имеют вызов отдыха, но не могут издеваться над фактический звонок. Может ли кто-нибудь провести меня сюда?

1 Ответ

0 голосов
/ 07 мая 2020

Вы не используете TestRestTemplate для той цели, для которой он предназначен.

TestRestTemplate не является расширением RestTemplate, а скорее альтернативой, которая упрощает интеграционное тестирование и облегчает аутентификацию во время тестов. Это помогает в настройке Apache HTTP-клиента, но также может использоваться как оболочка для RestTemplate

Решение:

Подход 1: 1) Непосредственно вызвать метод обмена с помощью RestTemplate

    ResponseEntity<String> response = restTemplate .exchange(url,HttpMethod.GET, null, String.class);

2) Создайте макет testRestTemplate и сделайте макет при вызове метода обмена для этого объекта.

    when(testRestTemplate.exchange(ArgumentMatchers.anyString(),
            ArgumentMatchers.any(HttpMethod.class),
            ArgumentMatchers.any(),
            ArgumentMatchers.<Class<BoundaryValueInfo[]>>any())
    ).thenReturn(answerFromApi);
...