有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何模拟日历。使用JMockit的getInstance方法?

我正在尝试使用JMockit模拟Calendar.getInstance()方法。这是我第一次嘲笑任何东西

下面是我的方法,它以YYYYMMDD的格式给出最近Monday或最近Thursday的日期

今天是星期天,所以它应该以YYYYMMDD的格式返回星期四的日期,所以它将是2014027

public static String getCorrectDate() {

    Calendar cal = Calendar.getInstance();

    try {
        int dow = cal.get(Calendar.DAY_OF_WEEK);
        switch (dow) {
        case Calendar.THURSDAY:
        case Calendar.FRIDAY:
        case Calendar.SATURDAY:
        case Calendar.SUNDAY:
        while (cal.get(Calendar.DAY_OF_WEEK) != Calendar.THURSDAY) {
            cal.add(Calendar.DATE, -1);
        }
        break;
        case Calendar.MONDAY:
        case Calendar.TUESDAY:
        case Calendar.WEDNESDAY:
        while (cal.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
            cal.add(Calendar.DATE, -1);
        }
        break;
        }
    } catch (Exception ex) {
        // log error
    }

    return toDateFormat.format(cal.getTime());
}

所以我的问题是,如何使用JMokcit模拟Calendar.getInstance方法,以便轻松地使用junit getCorrectDate方法

我以前从来没有嘲笑过它,所以我面临一些问题

如果可能的话,有人能提供一个简单的例子吗

我试图这样做,但它在MockClass上抱怨我,因为它无法解决。。我还添加了JMockit的maven依赖项

@MockClass(realClass = Calendar.class) 
class CalendarMock {
 private int hour;
 private int day;
 private int minute;

 public CalendarMock(int day, int hour, int minute) {
  this.hour = hour;
  this.day = day;
  this.minute = minute;
 }

 @Mock
 public int get(int id) {
  if (id == Calendar.HOUR_OF_DAY) {
   return hour;
  }
  if (id == Calendar.DAY_OF_WEEK) {
   return day;
  }

  if (id == Calendar.MINUTE) {
   return minute;
  }
  return -1;
 }
}

共 (2) 个答案

  1. # 1 楼答案

    public class CalendarTest {
    
        @Test
        public void testCalender() {
    
            new MockCalendar(1,2,3);
    
            Calendar c = Calendar.getInstance();
            int day = c.get(Calendar.HOUR_OF_DAY);
            Assert.assertEquals(day, 2);
        }
    
      public static class MockCalendar extends MockUp<Calendar> {
            private int hour;
            private int minute;
            private int day;
    
            public MockCalendar(int day, int hour, int minute) {
                this.hour = hour;
                this.minute = minute;
                this.day = day;
            }
            @Mock
            protected void $init() {}
    
            @Mock
            public static Calendar getInstance() {
                return new GregorianCalendar(1970,1,1);
            }
    
            @Mock
            public int get(int id) {
                if (id == Calendar.HOUR_OF_DAY) {
                    return hour;
                }
                if (id == Calendar.DAY_OF_WEEK) {
                    return day;
                }
    
                if (id == Calendar.MINUTE) {
                    return minute;
                }
                return -1;
            }
        }
     }
    
    }
    

    你可以增强做事的逻辑

  2. # 2 楼答案

    下面是getCorrectDate()方法的完整测试类(减去导入),使用JMockit 1.6中提供的两个模拟API:

    public class DateAdjustmentTest
    {
        final int year = 2014;
        final int month = Calendar.MARCH;
        final Calendar[] datesOnDifferentWeekdays = {
            new GregorianCalendar(year, month, 2), // a sunday
            new GregorianCalendar(year, month, 3), // a monday
            new GregorianCalendar(year, month, 4), // a tuesday
            new GregorianCalendar(year, month, 5), // a wednesday
            new GregorianCalendar(year, month, 6), // a thursday
            new GregorianCalendar(year, month, 7), // a friday
            new GregorianCalendar(year, month, 8), // a saturday
        };
    
        @Test
        public void getAdjustedDateAccordingToWeekday_usingExpectationsAPI()
        {
            new NonStrictExpectations(Calendar.class) {{
                // Each consecutive call to this method will return the next date.
                // Calls to other Calendar methods will not be mocked.
                Calendar.getInstance(); result = datesOnDifferentWeekdays;
            }};
    
            assertEachDayOfWeekGetsCorrectlyAdjusted();
        }
    
        void assertEachDayOfWeekGetsCorrectlyAdjusted()
        {
            String thursdayOfPreviousWeek = "27/02/2014";
            assertEquals(thursdayOfPreviousWeek, getCorrectDate());
    
            String mondayOfSameWeek = "03/03/2014";
            assertEquals(mondayOfSameWeek, getCorrectDate());
            assertEquals(mondayOfSameWeek, getCorrectDate());
            assertEquals(mondayOfSameWeek, getCorrectDate());
    
            String thursdayOfSameWeek = "06/03/2014";
            assertEquals(thursdayOfSameWeek, getCorrectDate());
            assertEquals(thursdayOfSameWeek, getCorrectDate());
            assertEquals(thursdayOfSameWeek, getCorrectDate());
        }
    
        @Test
        public void getAdjustedDateAccordingToWeekday_usingMockUpAPI()
        {
            new MockUp<Calendar>() {
                @Mock
                Calendar getInstance(Invocation inv)
                {
                    return datesOnDifferentWeekdays[inv.getInvocationIndex()];
                }
            };
    
            assertEachDayOfWeekGetsCorrectlyAdjusted();
        }
    }
    

    我想说这两个测试都非常简单,不需要更改原始的生产代码