如何使用mockito模拟在分层静态类下定义的最终变量?

时间:2015-06-05 17:38:38

标签: mockito static-class

我的代码如下

ScheExeService.ScheduleId scheduleID =   ScheExeService.getOneTimeScheduleId(nl.getCompany(), workItem.getId());
ScheExeService.Schedule schedule = ScheExeService.loadSchedule(nl, scheduleID.getId());
Calendar cal = Calendar.getInstance(java.util.TimeZone.getTimeZone(nl.getTimeZone()));
cal.setTime(schedule.attributes.startDate.toDate());

我正在尝试模拟" schedule.attributes.startDate.toDate()"

和ScheExeService如下所示

public class ScheExeService implements blah
{

  public final static class Schedule {
    public final ScheduleId id;
    public final ScheduleAttributes attributes;
    public final String callableClassName;
    public final long itemId;


 public Schedule(ScheduleId id, ScheduleAttributes attributes, String callableClassName, long itemId)
    {
        this.id = id;
        this.attributes = attributes;
        this.callableClassName = callableClassName;
        this.itemId = itemId;
    }
}
public final static class ScheduleAttributes {

    public final @Nullable LocalDate startDate;
    public final @Nullable LocalTime startTime;
    public final @Nullable LocalDate endDate;
    public final @Nullable LocalTime endTime;
Method code

}
}

我试过

 doNothing().doThrow(new RuntimeException()).when(mockedCalenderObject).setTime(null);

但我一直在接受NPE。

我怎样才能避免schedule.attributes.startDate.todate()调用..?

1 个答案:

答案 0 :(得分:0)

最好不要模拟像List和String这样的数据/值对象,包括像LocalDate和LocalTime这样的Joda对象,以及像Schedule和ScheduleAttributes这样的数据对象。这主要是因为,除非实例难以创建,否则您只需在测试中创建实例,并使getter和setter按预期运行。

另请参阅:"Test smell: Everything is mocked"

基于您的代码,我非常建议模拟loadSchedule(这可能需要重构ScheExeService而不是静态方法,重构被测系统的后半部分以接受任意的Schedule,或使用PowerMock)并使用真实电话创建测试时间表。

public void yourMethod(NL nl, WorkItem workItem) {
  ScheExeService.ScheduleId scheduleID =   ScheExeService.getOneTimeScheduleId(nl.getCompany(), workItem.getId());
  ScheExeService.Schedule schedule = ScheExeService.loadSchedule(nl, scheduleID.getId());
  processSchedule(schedule);
}

/**
 * Processes schedule for yourMethod. Exposed for testing: Create as many
 * arbitrary Schedules as you want and pass them in to test this thoroughly.
 */
void processSchedule(Schedule schedule) {
  Calendar cal = Calendar.getInstance(java.util.TimeZone.getTimeZone(nl.getTimeZone()));
  cal.setTime(schedule.attributes.startDate.toDate());
  // ...
}