【问题标题】:NullPointerException while using PowerMockito使用 PowerMockito 时出现 NullPointerException
【发布时间】:2020-12-28 14:48:42
【问题描述】:

模拟 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 被嘲笑,也无法准确解决问题。这里试图获取日历对象。

【问题讨论】:

  • - 首先,最好将您的代码设计为 TESTABLE,这意味着您不需要 PowerMockito。避免使用 PowerMockito 将帮助您的代码更清晰,设计更好......其次,阅读此内容并确保您没有遗漏任何内容:baeldung.com/intro-to-powermock。最后,NPE 是最简单的问题。只需在导致 NPE 的地方放置一个断点,看看什么是空的。
  • 欢迎来到 Stack Overflow。请通过tour 了解 Stack Overflow 的工作原理,并阅读How to Ask 以了解如何提高问题的质量。然后edit 你的问题包括你作为minimal reproducible example 的完整源代码,其他人可以编译和测试。当您运行 junit 测试时,还要添加完整的异常消息,包括您获得的堆栈跟踪。
  • 你为什么使用eq()而不是直接值"America/Cambridge_Bay"
  • 检查默认字符串值。如果不使用,则在下面给出 exception.org.mockito.exceptions.misusing.MissingMethodInvocationException: when() 需要一个必须是“模拟方法调用”的参数。例如:when(mock.getArticles()).thenReturn(articles);

标签: java junit mockito static-methods powermock


【解决方案1】:

通过为 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
        }

【讨论】:

    猜你喜欢
    • 2013-12-29
    • 2013-12-19
    • 2022-01-19
    • 2013-04-13
    • 2014-11-11
    • 2012-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多