使用 @InjectMock 给 URI 不是绝对错误

Using @InjectMock giving URI not absolute error

我已经为使用 rest 模板调用另一个服务的方法编写了以下 Junit,但模拟抛出 URI not absolute 错误。

方法:

@Value("${app.prop.esso-url}")
private String essoUrl;

public  ResponseEntity<String> essoCall(String token) {

    ResponseEntity<String> response=null;
    RestTemplate restTemplate = new RestTemplate();

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    headers.add("Accept", MediaType.APPLICATION_JSON_VALUE);
    headers.setBearerAuth(token);

    HttpEntity<String> entity = new HttpEntity<>(headers);
    response= restTemplate.exchange(essoUrl, HttpMethod.GET, entity,String.class);

    logger.info("successfully received response.");
    return response;
}

单位:

@Autowired
private ObjectMapper objectMapper;

@InjectMocks
SecurityMsServiceImpl securityservice=new SecurityMsServiceImpl();



@Value("${app.prop.esso-url}")
private String essoUrl;

@Mock
private RestTemplate restTemplate;


@Test
    void givenMockingIsDoneByMockito_whenGetIsCalled_shouldReturnMockedObject() {
    ResponseEntity<String> responseEntity = new ResponseEntity<String>("success", HttpStatus.OK);
    Mockito
        .when(restTemplate.getForEntity(essoUrl
        , String.class))
        .thenReturn(responseEntity);

    ResponseEntity<String> finalresponse=securityservice.essoCall("abc");
    assertEquals(responseEntity, finalresponse);
}

我一次又一次看到这个问题:

您正在测试的方法中构建 RestTemplate 的新实例。 您应该做的是将它注入到您的 bean 中,这意味着:

  • 在您的 bean 中添加一个类型为 RestTemplate 的字段
  • 在构造函数中初始化它
  • 在测试中,传入模拟实例
  • 在产品中,通过 Spring DI
  • 传入常规实例

RestTemplate 是线程安全的,它的一个实例是完全有效的。 参见 Is RestTemplate thread safe?

最重要的是:

  • 我的建议是使用构造函数注入而不是字段注入
  • 您正在混合使用 Spring 的 @Autowired 和 Mockito 的 @InjectMocks。选择是否要使用 MockitoExtension 或 SpringExtension 进行测试,并选择适当的一组注释来初始化您的 SUT。