繁体   English   中英

如何避免 NullPointerException Junit RestTemplate

[英]How to avoid NullPointerException Junit RestTemplate

我在 spring 项目中工作,我有一个使用 Restemplate 调用另一个 api 的服务,该服务仅返回一个字符串作为令牌,并且对我来说一切正常,这是我的服务:

@Service
public class AppServiceImpl {

    @Value("${rest.appUrl}")
    private String appUrl;

    @Value("${credType}")
    private String credType;

    @Autowired
    private RestTemplate restTemplate;

    public String getToken() {

        HttpHeaders headers = new HttpHeaders();

        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();

        map.add("grant_type", credType);

        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);

        ResponseEntity<TargetObject> response = restTemplate.exchange(appUrl, HttpMethod.POST, request, TargetObject.class);

        TargetObject targetObject = response.getBody();

        return "Bearer " + targetObject.getToken();

    }

}

我的问题是当我想对这个服务进行单元测试时,我收到 NullPointerException 并且我不知道为什么,这是我的单元测试:

@RunWith(SpringRunner.class)
public class AppServiceImplTest {

    private AppService appService = new AppServiceImpl();

    @Test
    public void getTokenTest() {

        String token = appService.getToken();

        assertTrue(token != null);
    }

}

此行中的 NullPointerException :

ResponseEntity<TargetObject> response = restTemplate.exchange(appUrl, HttpMethod.POST, request, TargetObject.class);

你知道我的测试有什么问题吗? 我花了几个小时没有任何结果

提前致谢

你的问题是在你的服务中你自动装配了restTemplate ,但是在你的测试中你自己初始化你的类,而不是通过 spring,因为它没有初始化并保持为空。

如果您在测试中自己初始化服务,请确保添加restTemplate实例。 我建议将服务中的 autowire 移动到基于 c'tor 的,然后在测试中很容易做到这一点:

 @Service
 public class AppServiceImpl {

    private String appUrl;
    private String credType;
    private RestTemplate restTemplate;

    public AppServiceImpl(RestTemplate restTemplate, @Value("${credType}") String credType, @Value("${rest.appUrl}") String appUrl) {
      this.restTemplate = restTemplate;
      this.credType = credType;
      this.appUrl = appUrl;
    }

...
...
...
}

稍后在您的测试中:

@Mock private RestTemplate restTamplate;
private AppService appService;

@Before
public void setup() {
  appService = new AppServiceImpl(restTamplate);
}

使用 Mockito 它将解决您的问题。

ResponseEntity<TargetObject> response = restTemplate.exchange(appUrl, HttpMethod.POST, 
     request, TargetObject.class);

以上代码的junit将是:

@Mock
private RestTemplate restTemplate;

TargetObject targetObject = new TargetObject();
targetObject.setToken("123456");
Mockito.when( restTemplate.exchange(Mockito.anyString(),Mockito.any(HttpMethod.class), 
   Mockito.any(HttpEntity.class),Mockito.any(TargetObject.class)).thenReturn(targetObject);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM