0

我正在尝试模拟 restClient 外部 API,但它正在调用实际的 API 而不是模拟它。请提供帮助,因为我不确定我哪里出错了。

我尝试嘲笑电话和其他一些事情,但没有奏效。

public class TestService
{
    private static final String EXTERNAL_API = "http://LinktoExternalAPI/";

    @Autowired
    RestTemplate restTemplate;


    public  Map<String, String> countryCodes()
    {
        Map<String, String> map = new TreeMap<>();

        try
        {
            ResponseEntity<testCountry[]> responseEntity = restTemplate
                    .getForEntity(EXTERNAL_API
                            , testCountry[].class);
            List<testCountry> testCountryList = Arrays.asList(responseEntity.getBody());
            map = testCountryList.stream()
                    .collect(Collectors.toMap(testCountry::getCode, testCountry::getName));
        }

        catch (HttpClientErrorException | HttpServerErrorException httpClientOrServerExc)
        {

        }

        return map;
    }
}

测试用例如下:

@RunWith(PowerMockRunner.class)
public class TestServiceTest
{
    @InjectMocks
    TestService testService;

    @Mock
    RestTemplate restTemplate;

    private static final String EXTERNAL_API = "http://LinktoExternalAPI/";

    @Test
    public void testCountryCodes(){

        TestCountry testCountry = new TestCountry();
        testCountry.setCode("JPN");
        testCountry.setName("Japan");

        List<testCountry> testCountryList = new ArrayList<testCountry>();
        testCountryList.add(testCountry);

        Mockito.when(restTemplate.getForEntity(EXTERNAL_API, testCountry[].class)).thenReturn(new ResponseEntity(testCountryList, HttpStatus.OK));
        Map<String, String> result = testService.countryCodes();

        // result is pulling the actual size of the api instead of mocking and sending me testCountryList size.
        <Will mention assertion here>
    }

结果是拉取 API 的实际大小,而不是模拟并发送给我testCountryList大小。

4

2 回答 2

1

调用实际 API 背后的原因可能是您正在模拟的 URL 与运行时生成的 URL 不完全相同,因此未找到模拟并调用实际 API。在这些情况下,您可以使用Mockito.any().

所以模拟代码将是Mockito.when(restTemplate.getForEntity(Mockito.any(), Mockito.any())).thenReturn(new ResponseEntity(testCountryList, HttpStatus.OK));

@RunWith(MockitoJUnitRunner.class)
public class TestServiceTest {

  @InjectMocks
  private TestService testService;

  @Mock
  private RestTemplate restTemplate;

  @Test
  public void testCountryCodes(){

    TestCountry testCountry = new TestCountry();
    testCountry.setCode("JPN");
    testCountry.setName("Japan");

    TestCountry[] testCountryList = {
        testCountry
    };

    Mockito.when(restTemplate.getForEntity(Mockito.anyString(), Mockito.any())).thenReturn(new ResponseEntity(testCountryList, HttpStatus.OK));

    Map<String, String> result = testService.countryCodes();

    // result is pulling the actual size of the API instead of mocking and sending me testCountryList size.

  }
}

也尝试使用@RunWith(MockitoJUnitRunner.class)而不是PowerMockRunner.class因为您似乎不需要 PowerMock 功能。

于 2019-10-30T08:47:48.810 回答
0

您在嘲笑错误的方法定义。

一个getForObject带参数的方法String并且Class不存在。您需要为this方法定义行为。

请注意,在您的情况下,不使用第三个参数(可变参数),因此它默认为空数组。但是Mockito需要这些信息来模拟正确的调用。

Mockito.when(restTemplate.getForObject(any(String.class), any(Class.class), ArgumentMatchers.<Object>any()))
       .thenReturn(result);

有关更完整的示例,请在此处查看我的答案。

于 2019-10-31T09:43:50.700 回答