当前位置: 首页 > 知识库问答 >
问题:

RestTemplate模拟会产生NullPointerException

喻渊
2023-03-14

我的服务等级代码如下:

public class MyServiceImpl implements MegatillAccessService {
@Autowired
RestTemplate restTemplate;

@Value("${api.key}")
private String apiKey;

@Value("${customers.url}")
private String postUrl;

@Override
public String pushCustomerData(List<Customer> listOfcustomers, String storeId) throws MyServiceException {

Set<Customer> setOfCustomers = new HashSet<>(listOfcustomers);
    int noOfCustomersLoadedSuccessfully =0;

    MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
    headers.add("apiKey", apiKey);
    headers.add("Content-Type", "application/json");
    headers.add("storeId", storeId);
    restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());

    for(Customer customer: setOfCustomers){
        HttpEntity<Customer> request = new HttpEntity<Customer>(customer, headers);
        CustomerDataDto customerDataDto = null;
        try {
            customerDataDto = restTemplate.exchange(postUrl, HttpMethod.POST, request, CustomerDataDto.class).getBody();
        }
        catch (HttpClientErrorException ex) {
            if (ex.getStatusCode().equals(HttpStatus.NOT_FOUND)) {
                log.error("The customers service is not available to load data: "+ ex.getResponseBodyAsString(), ex);
                throw new MyServiceException("The customers service is not available to load data",new RuntimeException(ex));
            }
            else{
                log.warn("Error for customer with alias: "+customer.getAlias() +" with message: "+ ex.getResponseBodyAsString(), ex);
                if(!ex.getResponseBodyAsString().contains("already found for this shop")){
                    throw new MyServiceException("An error occurred while calling the customers service with status code "+ex.getStatusCode(),new RuntimeException(ex));
                }
            }
        }
        catch(Exception e){
            throw new MyServiceException("An error occurred while calling the customers service: ",new RuntimeException(e));
        }

        if(null != customerDataDto) {
            noOfCustomersLoadedSuccessfully++;
            log.debug("--------Data posted successfully for: ---------"+customerDataDto.getAlias());
        }
    }
    String messageToReturn = "No. of unique customers from source: "+setOfCustomers.size()+". No. of customers loaded to destination without error: "+noOfCustomersLoadedSuccessfully;
    return messageToReturn;
}
}

我的测试课程如下:

@RunWith(MockitoJUnitRunner.class)
@SpringBootTest
public class MyServiceTest {

@InjectMocks
private MyService myService = new MyServiceImpl();

@Mock
RestTemplate restTemplate;

@Before
public void setUp() throws Exception
{
    MockitoAnnotations.initMocks(this);
    initliaizeModel();
    restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
}

@Test
public void pushAllRecords(){

    Mockito.when(restTemplate.exchange(Matchers.anyString(), Matchers.any(HttpMethod.class), Matchers.<HttpEntity<?>> any(), Matchers.<Class<CustomerDataDto>> any()).getBody()).thenReturn(customerDataDto);

    /*Mockito.when(restTemplate.exchange(Mockito.anyString(),
            Mockito.<HttpMethod> eq(HttpMethod.POST),
            Matchers.<HttpEntity<?>> any(),
            Mockito.<Class<CustomerDataDto>> any()).getBody()).thenReturn(customerDataDto);*/

    String resultReturned = myService.pushCustomerData(customers,"1235");
    assertEquals(resultReturned, "No. of unique customers from source: 2. No. of customers loaded to destination without error: 2");
}

}

在运行测试时,我在给出Mockito的那一行得到了NullPointerException。何时返回条件。我尝试了很多组合,但它仍然提供NPE。我甚至连方法调用都做不到。你能告诉我哪里出了问题吗?

共有1个答案

濮阳唯
2023-03-14

你会得到NullPointerException,因为你在Mockito中做的太多了。当。当时,您的代码在中(较短版本):

rest模板。交换(args)。getBody()

您试图模拟getBody(),但它在Exchange(args)上被调用。什么是交换(args)返回?Mockito不知道它应该返回什么,你也没有指定它,所以默认情况下它返回null

这就是为什么你会得到NPE。

要解决这个问题,你可以一步一步地模仿。

ResponseEntity re = Mockito.when(exchange.getBody()).thenReturn(customerDataDto);
Mockito.when(restTemplate.exchange()).thenReturn(re);

或者指定mock来返回深存根,就像这样(如果您想使用注释):

@Mock(answer = Answers.RETURNS_DEEP_STUBS)
RestTemplate restTemplate;

 类似资料:
  • 我的要求是测试这段代码,更重要的是测试序列化器,因此,给出一个JSON片段,我如何测试所有的值都正确地通过商人的实例。 我不知道RestTemplate使用哪个序列化器将JSON序列化为对象。

  • 它返回null,而不是预期的客户端,对象类的工作正常。我只想写测试。我是漏掉了什么还是做错了测试?谢谢你的指导。

  • 我试图测试一个简单POST Rest调用,但存在NullPointerException。 我的RestController: 我的单元测试: 由于以下错误,此测试失败:NullPointerException,确切地说,response ResponseEntity对象为Null。 verify输出将执行以下操作: 知道为什么响应是空的吗?我为测试使用了正确的注释,因此应该注入模拟。也许我在这里

  • 我现在在运行时看到.Intercept正在获得null对象值。 有人能建议我怎么修理吗。

  • 我在这里遵循指南,我成功地在我的beanendpoint上配置了一个生产者,如下所示: 是: 还有我的豆子: 现在,我如何测试这个?我的意思是:我的测试扩展了CamelTestSupport,我用 也就是说:我复制了camel上下文,但没有配置spring上下文,我希望(如果可能的话)避免实例化它。 如何模拟生产者或使Camel实例化并将此bean注入我的beanendpoint?使用Apache

  • 问题内容: 我有MockRestServiceServer来模拟服务中的restTemplete。但是它总是失败。它显示错误为。任何人都可以让我知道我在哪里做错了。 服务本身将如下所示: 问题答案: 首先,您的类会在每个请求上创建一个RestTemplate的新实例。我不能足够强调这种不良做法。创建一个类型为RestTemplate的bean并将其注入到您的bean中(它很可能已经创建- 取决于您