hzdavid / jmockit.cn

JMockit中文网(jmockit.cn)上所有讲述的测试示例源代码
36 stars 15 forks source link

Mocked Calendar 为录制过get(C.DAY_OF_MONTH),并不是返回默认值,而是报错,这是为什么呢?? #24

Closed yymoxiaochi closed 4 years ago

yymoxiaochi commented 5 years ago

public class ExpectationsTest { @Mocked Calendar cal;

@Test
public void testRecordOutside() {
    new Expectations() {
        {
            // 对cal.get方法进行录制,并匹配参数 Calendar.YEAR
            cal.get(Calendar.YEAR);
            result = 2016;// 年份不再返回当前小时。而是返回2016年
            // 对cal.get方法进行录制,并匹配参数 Calendar.HOUR_OF_DAY
            cal.get(Calendar.HOUR_OF_DAY);
            result = 7;// 小时不再返回当前小时。而是返回早上7点钟
        }
    };
    Assert.assertTrue(cal.get(Calendar.YEAR) == 2016);
    Assert.assertTrue(cal.get(Calendar.HOUR_OF_DAY) == 7);
    // 因为没有录制过,所以这里月份返回默认值 0
    Assert.assertTrue(cal.get(Calendar.DAY_OF_MONTH) == 0);
}

} 报错: mockit.internal.UnexpectedInvocation: Unexpected invocation of: java.util.Calendar#get(int) with arguments: 5

yymoxiaochi commented 5 years ago

修改一下:未录制过。。。

hzdavid commented 5 years ago

这种情况,需要使用 MockUp

import java.util.Calendar;

import org.junit.Assert; import org.junit.Test;

import mockit.Expectations; import mockit.Invocation; import mockit.Mock; import mockit.MockUp; import mockit.Mocked;

public class ExpectationsTest {

@Test
public void testRecordOutside(@Mocked Calendar cal) {
    new Expectations() {
        {
            // 对cal.get方法进行录制,并匹配参数 Calendar.YEAR
            cal.get(Calendar.YEAR);
            result = 2016;// 年份不再返回当前小时。而是返回2016年
            // 对cal.get方法进行录制,并匹配参数 Calendar.HOUR_OF_DAY
            cal.get(Calendar.HOUR_OF_DAY);
            result = 7;// 小时不再返回当前小时。而是返回早上7点钟
        }
    };
    Assert.assertTrue(cal.get(Calendar.YEAR) == 2016);
    Assert.assertTrue(cal.get(Calendar.HOUR_OF_DAY) == 7);
    // 因为没有录制过,所以这里月份返回默认值 0
    Assert.assertTrue(cal.get(Calendar.DAY_OF_MONTH) == 0);
}

@Test
public void testRecordOutside1() {

    new MockUp<Calendar>(Calendar.class) {
        // 想Mock哪个方法,就给哪个方法加上@Mock, 没有@Mock的方法,不受影响
        @Mock
        public int get(Invocation invocation, int unit) {
            if (unit == Calendar.YEAR) {
                return 2016;
            }
            if (unit == Calendar.HOUR_OF_DAY) {
                return 7;
            }
            return invocation.proceed(unit);
        }
    };
    Calendar cal = Calendar.getInstance();
    Assert.assertTrue(cal.get(Calendar.YEAR) == 2016);
    Assert.assertTrue(cal.get(Calendar.HOUR_OF_DAY) == 7);
    // 今天是8-23号,这里返回23. 你根据情况改。
    Assert.assertTrue(cal.get(Calendar.DAY_OF_MONTH) == 23);
}

}

hzdavid commented 5 years ago

这里有详细解释 :如何在Mock方法中调用老方法

http://www.jmockit.cn/showArticle.htm?channel=4&id=18

yymoxiaochi commented 5 years ago

这里有详细解释 :如何在Mock方法中调用老方法

http://www.jmockit.cn/showArticle.htm?channel=4&id=18

我的意思是,已经使用了 @Mocked 修饰该方法了,按道理来说,里面所有未录制的方法返回的都是递归的默认值null或者0. 但是我本地如下代码时,会报错,为什么呢?

// 因为没有录制过,所以这里月份返回默认值 0
Assert.assertTrue(cal.get(Calendar.DAY_OF_MONTH) == 0);
hzdavid commented 5 years ago

请用JMockit 1.36 ,下面的test并不会报错,

`public class ExpectationsTest { @Mocked Calendar cal;

@Test public void testRecordOutside() { new Expectations() { { // 对cal.get方法进行录制,并匹配参数 Calendar.YEAR cal.get(Calendar.YEAR); result = 2016;// 年份不再返回当前小时。而是返回2016年 // 对cal.get方法进行录制,并匹配参数 Calendar.HOUR_OF_DAY cal.get(Calendar.HOUR_OF_DAY); result = 7;// 小时不再返回当前小时。而是返回早上7点钟 } }; Assert.assertTrue(cal.get(Calendar.YEAR) == 2016); Assert.assertTrue(cal.get(Calendar.HOUR_OF_DAY) == 7); // 因为没有录制过,所以这里月份返回默认值 0 Assert.assertTrue(cal.get(Calendar.DAY_OF_MONTH) == 0); } }`

yymoxiaochi commented 5 years ago

@Mocked Calendar cal;

@test public void testRecordOutside() { new Expectations() { { // 对cal.get方法进行录制,并匹配参数 Calendar.YEAR cal.get(Calendar.YEAR); result = 2016;// 年份不再返回当前小时。而是返回2016年 // 对cal.get方法进行录制,并匹配参数 Calendar.HOUR_OF_DAY cal.get(Calendar.HOUR_OF_DAY); result = 7;// 小时不再返回当前小时。而是返回早上7点钟 } }; Assert.assertTrue(cal.get(Calendar.YEAR) == 2016); Assert.assertTrue(cal.get(Calendar.HOUR_OF_DAY) == 7); // 因为没有录制过,所以这里月份返回默认值 0 Assert.assertTrue(cal.get(Calendar.DAY_OF_MONTH) == 0); }

可以啦。不知道之前是什么原因,,,版本也是1.36,总之谢谢啦🙏