【问题标题】:How to avoid NullPointerException Junit RestTemplate如何避免 NullPointerException Junit RestTemplate
【发布时间】:2020-01-31 15:21:21
【问题描述】:

我在 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);

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

提前致谢

【问题讨论】:

    标签: java junit


    【解决方案1】:

    您的问题是,在您的服务中,您自动连接 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);
    }
    

    【讨论】:

    • 你好@Nir我做了你所说的改变,但仍然存在同样的问题Nullpointer Exception in this line ResponseEntity response = restTemplate.exchange(appUrl, HttpMethod.POST, request, TargetObject.class);
    • 你调试了吗?什么是空的,仍然是restTemplate?它是在测试代码中正确定义还是 null 那里?
    • 当我调用 response.getBody() 时响应为空,它给了我 NullPointerExcep
    • @James 所以你错过了 restTemplate 的 Mockito.when() 分配
    【解决方案2】:

    使用 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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-01
      • 1970-01-01
      • 2021-05-21
      • 2011-11-20
      • 2019-01-15
      • 2016-12-01
      • 2019-04-18
      • 1970-01-01
      相关资源
      最近更新 更多