使用 PowerMockito 时出现 NullPointerException
NullPointerException while using PowerMockito
模拟 getTimeZone 方法时出现空指针异常。 defaultSystemTimezone 由 属性 文件填充。
SummaryServiceTest.java:
@RunWith(PowerMockRunner.class)
@PrepareForTest({Calendar.class, TimeZone.class})
@ExtendWith(SpringExtension.class)
class SummaryServiceTest{
@Mock
BookingRepository bookingRepository;
@InjectMocks
private SummaryService summaryService;
@Before
public void setup(){
MockitoAnnotations.initMocks(this);
}
@Test
public void getBookingRejections() throws Exception {
TimeZone timezoneObj = TimeZone.getTimeZone("America/Cambridge_Bay");
PowerMockito.mockStatic(TimeZone.class);
Mockito.when(TimeZone.getTimeZone(eq("America/Cambridge_Bay"))).thenReturn(timezoneObj);
Calendar calendar1 = Calendar.getInstance(TimeZone.getDefault(), Locale.US);
Calendar ac = PowerMockito.mock(Calendar.class);
PowerMockito.doReturn(calendar1).when(ac , "getInstance");
Boolean bookingRejectionsByWeekForCarrierList = summaryService.getBookingRejections();
}
}
SummaryService.java:
@Service
public class SummaryService {
@Autowired
private BookingRepository bookingRepository;
@Value("${timezone.default}")
private String defaultSystemTimezone;
public Boolean getBookingRejections() {
Calendar calendarFirstDayOfWeek = Calendar.getInstance(TimeZone.getTimeZone(defaultSystemTimezone), Locale.US);
return true;
}
}
application.properties:
timezone.default=America/Cambridge_Bay
低于异常:
java.lang.NullPointerException
at java.util.TimeZone.parseCustomTimeZone(TimeZone.java:783)
at java.util.TimeZone.getTimeZone(TimeZone.java:562)
at java.util.TimeZone.getTimeZone(TimeZone.java:516)
at com.booking.service.SummaryServiceTest.getBookingRejections(SummayServiceTest.java:)
即使模拟了 TimeZone 也无法准确解决问题。这里试图获取日历对象。
通过为 SummaryService 的 defaultSystemTimezone 变量添加 setter 解决了这个问题。
并在测试方法中设置var的值。
SummaryService.java:
@Service
public class SummaryService {
@Autowired
private BookingRepository bookingRepository;
@Setter
@Value("${timezone.default}")
private String defaultSystemTimezone;
public Boolean getBookingRejections() {
Calendar calendarFirstDayOfWeek = Calendar.getInstance(TimeZone.getTimeZone(defaultSystemTimezone), Locale.US);
return true;
}
}
@Test
public void getBookingRejections() throws Exception {
summaryService.setDefaultSystemTimezone("America/Cambridge_Bay");
//execute test
}
模拟 getTimeZone 方法时出现空指针异常。 defaultSystemTimezone 由 属性 文件填充。
SummaryServiceTest.java:
@RunWith(PowerMockRunner.class)
@PrepareForTest({Calendar.class, TimeZone.class})
@ExtendWith(SpringExtension.class)
class SummaryServiceTest{
@Mock
BookingRepository bookingRepository;
@InjectMocks
private SummaryService summaryService;
@Before
public void setup(){
MockitoAnnotations.initMocks(this);
}
@Test
public void getBookingRejections() throws Exception {
TimeZone timezoneObj = TimeZone.getTimeZone("America/Cambridge_Bay");
PowerMockito.mockStatic(TimeZone.class);
Mockito.when(TimeZone.getTimeZone(eq("America/Cambridge_Bay"))).thenReturn(timezoneObj);
Calendar calendar1 = Calendar.getInstance(TimeZone.getDefault(), Locale.US);
Calendar ac = PowerMockito.mock(Calendar.class);
PowerMockito.doReturn(calendar1).when(ac , "getInstance");
Boolean bookingRejectionsByWeekForCarrierList = summaryService.getBookingRejections();
}
}
SummaryService.java:
@Service
public class SummaryService {
@Autowired
private BookingRepository bookingRepository;
@Value("${timezone.default}")
private String defaultSystemTimezone;
public Boolean getBookingRejections() {
Calendar calendarFirstDayOfWeek = Calendar.getInstance(TimeZone.getTimeZone(defaultSystemTimezone), Locale.US);
return true;
}
}
application.properties:
timezone.default=America/Cambridge_Bay
低于异常:
java.lang.NullPointerException
at java.util.TimeZone.parseCustomTimeZone(TimeZone.java:783)
at java.util.TimeZone.getTimeZone(TimeZone.java:562)
at java.util.TimeZone.getTimeZone(TimeZone.java:516)
at com.booking.service.SummaryServiceTest.getBookingRejections(SummayServiceTest.java:)
即使模拟了 TimeZone 也无法准确解决问题。这里试图获取日历对象。
通过为 SummaryService 的 defaultSystemTimezone 变量添加 setter 解决了这个问题。 并在测试方法中设置var的值。
SummaryService.java:
@Service
public class SummaryService {
@Autowired
private BookingRepository bookingRepository;
@Setter
@Value("${timezone.default}")
private String defaultSystemTimezone;
public Boolean getBookingRejections() {
Calendar calendarFirstDayOfWeek = Calendar.getInstance(TimeZone.getTimeZone(defaultSystemTimezone), Locale.US);
return true;
}
}
@Test
public void getBookingRejections() throws Exception {
summaryService.setDefaultSystemTimezone("America/Cambridge_Bay");
//execute test
}