无法调用“”,因为“”为 null mockito /junit
Cannot invoke "" because "" is null mockito /junit
根据标题,我在测试服务时遇到了一个问题method.I假设它应该是一些配置问题或者更多是 mockito 的错误使用。
有 CustomerDataService 的代码
@Service
public class CustomerDataService {
@Autowired
CustomerDataRepository customerDataRepository;
...
@Transactional
public void methodTotest(boolean consent, Long dialogId) {
CustomerData customer = customerDataRepository.findCustomerByDialogId(dialogId);
if (!consent) {
customerDataRepository.deleteById(customer.getCustomerId());
}else{
customer.setConsentGiven(true);
customerDataRepository.save(customer);
}
}
在测试CustomerDataServiceTest
@SpringBootTest
class客户数据服务测试{
@Autowired
CustomerDataService customerDataService;
@MockBean
CustomerDataRepository customerDataRepository;
@Test
void removeCustomerDataWhenConsentIsNotGiven() {
CustomerData customerDataTest = customerData;
//when
customerDataService.giveConsent(false,22L);
//then
verify(customerDataRepository,times(1)).save(customerDataTest);
}
错误是
java.lang.NullPointerException: Cannot invoke "com.mypackage.CustomerData.getCustomerId()" because "customer" is null
这是myMethod的第二行
提前致谢
假设您刚刚在将其发布到 Whosebug 之前更正了方法名称,并且您在测试中调用的方法:giveConsent
实际上与 CustomerDataService 的 methodTotest
是相同的方法。
在调用 customerDataService.giveConsent(false,22L);
之前,您需要将存储库配置为 return 一些测试(非空!或模拟)customerData 实体:
when(customerDataRepository.findCustomerByDialogId(22L)).thenReturn(customerDataTest);
customerDataService.giveConsent(false,22L);
注意:由于您将 false
作为第一个变量传递,因此您将进入此代码分支
if (!consent) {
customerDataRepository.deleteById(customer.getCustomerId());
}
并且在测试中您期望调用 save()
方法,因此测试将失败。
解决方法很简单。你模拟了一个 class customerDataRepository
但没有指示模拟如果调用相应的方法该做什么。 Mockito 模拟然后通过方法调用默认返回 doing nothing
,如果有 return 值 return null
。
由于您的 returned customerData 为空,因此您在调用此对象时会得到 NPE。在您的情况下,这是您通过调用 getCustomerId()
.
得到的错误情况
要解决此问题,只需指示您的模拟
@Test
void removeCustomerDataWhenConsentIsNotGiven() {
CustomerData customerDataTest = customerData;
//when
Mockito.when(customerDataRepository.findCustomerByDialogId(Mockito.any())).thenReturn(new CustomerData()); // <-- Add this line
customerDataService.giveConsent(false,22L);
//then
verify(customerDataRepository,times(1)).save(customerDataTest);
}
您显然可以将 Mockito.any()
替换为 Mockito.anyInt()
或 42
并将 new CustomerData()
替换为您之前创建的对象。我想你明白了 ;)
根据标题,我在测试服务时遇到了一个问题method.I假设它应该是一些配置问题或者更多是 mockito 的错误使用。
有 CustomerDataService 的代码
@Service
public class CustomerDataService {
@Autowired
CustomerDataRepository customerDataRepository;
...
@Transactional
public void methodTotest(boolean consent, Long dialogId) {
CustomerData customer = customerDataRepository.findCustomerByDialogId(dialogId);
if (!consent) {
customerDataRepository.deleteById(customer.getCustomerId());
}else{
customer.setConsentGiven(true);
customerDataRepository.save(customer);
}
}
在测试CustomerDataServiceTest @SpringBootTest class客户数据服务测试{
@Autowired
CustomerDataService customerDataService;
@MockBean
CustomerDataRepository customerDataRepository;
@Test
void removeCustomerDataWhenConsentIsNotGiven() {
CustomerData customerDataTest = customerData;
//when
customerDataService.giveConsent(false,22L);
//then
verify(customerDataRepository,times(1)).save(customerDataTest);
}
错误是
java.lang.NullPointerException: Cannot invoke "com.mypackage.CustomerData.getCustomerId()" because "customer" is null
这是myMethod的第二行 提前致谢
假设您刚刚在将其发布到 Whosebug 之前更正了方法名称,并且您在测试中调用的方法:giveConsent
实际上与 CustomerDataService 的 methodTotest
是相同的方法。
在调用 customerDataService.giveConsent(false,22L);
之前,您需要将存储库配置为 return 一些测试(非空!或模拟)customerData 实体:
when(customerDataRepository.findCustomerByDialogId(22L)).thenReturn(customerDataTest);
customerDataService.giveConsent(false,22L);
注意:由于您将 false
作为第一个变量传递,因此您将进入此代码分支
if (!consent) {
customerDataRepository.deleteById(customer.getCustomerId());
}
并且在测试中您期望调用 save()
方法,因此测试将失败。
解决方法很简单。你模拟了一个 class customerDataRepository
但没有指示模拟如果调用相应的方法该做什么。 Mockito 模拟然后通过方法调用默认返回 doing nothing
,如果有 return 值 return null
。
由于您的 returned customerData 为空,因此您在调用此对象时会得到 NPE。在您的情况下,这是您通过调用 getCustomerId()
.
要解决此问题,只需指示您的模拟
@Test
void removeCustomerDataWhenConsentIsNotGiven() {
CustomerData customerDataTest = customerData;
//when
Mockito.when(customerDataRepository.findCustomerByDialogId(Mockito.any())).thenReturn(new CustomerData()); // <-- Add this line
customerDataService.giveConsent(false,22L);
//then
verify(customerDataRepository,times(1)).save(customerDataTest);
}
您显然可以将 Mockito.any()
替换为 Mockito.anyInt()
或 42
并将 new CustomerData()
替换为您之前创建的对象。我想你明白了 ;)