如何使用可变数据初始化Mock

时间:2011-08-15 10:49:20

标签: java mockito

我有这个方法来测试:

public static Date getDateSinceUTC(CstOrderBean orderBean) {

    int year = orderBean.getDeadLineYear();
    int month = orderBean.getDeadLineMonth();
    int day = orderBean.getDeadLineDay();
    int hour = orderBean.getDeadLineHour();
    int minute = orderBean.getDeadLineMinute();
    String ap = orderBean.getDeadLineAmPm() == 1 ? "PM" : "AM";

    //TODO   AM=0, PM=1  comes from html form
    SimpleDateFormat df = new SimpleDateFormat("yyyy:MM:dd:hh:mm:aa");
    String stringDate = stringifyIntegers(":", year, month, day, hour, minute); 
    stringDate = stringDate.concat(ap);

    Date date;
    try {
        date = df.parse(stringDate);
    } catch (ParseException e) {
        throw new Error("Parsing date from html form failed", e);
    }
    return date;
}

CstOrderBean需要被Mockito模拟,因为它不是POJO(一些静态初始化等 - 来自源代码生成器)。但我需要运行xxx次方法,因此设置了具有许多数据组合的模拟

我可以使用TestNG的@DataProvider来做到这一点。但我不知道该怎么做,我猜:

    when(ob.getDeadLineYear()).thenReturn(1, 2, 3);
     ....
循环中的一个坏主意,不是吗?这样做的正确方法是创建xx模拟并将其初始化吗?

2 个答案:

答案 0 :(得分:1)

每个测试都应该得到自己的模拟,最好没有可变数据。如果您使用来自同一模拟对象的多个不同返回值,那么测试必须是白盒测试,因为测试与模拟方法的调用数相结合,而不是测试方法的结果。

也就是说,您可以通过重复调用thenReturn或将返回值定义为varargs来定义一组返回值

when(ob.getDeadLineYear()).thenReturn(someValue, anotherValue, ..., ultimateValue);

这可能更干净,因为您应该控制模拟返回的值。

答案 1 :(得分:0)

你如何模拟取决于你想要测试的内容。在截止日期前循环可能无法完成您想要的工作。

查看闰年是否有效的一项测试可能类似于:

when(ob.getDeadLineYear()).thenReturn(2000);
when(ob.getDeadLineMonth()).thenReturn(2);
when(ob.getDeadLineDay()).thenReturn(29);
when(ob.getDeadLineHour()).thenReturn(12);
when(ob.getDeadLineMinute()).thenReturn(0);
when(ob.getDeadDeadLineAmPm()).thenReturn(1);

assertTrue("Got unexpected date", getDateSinceUTC(ob).toString().startsWith("2000-02-29 12:00:00"));

(警告:上面的代码是手工输入的)。混合,匹配并重复其他日期您需要测试以验证getDateSinceUTC是否正常工作。您可能需要一个单独的测试方法来检查无效日期,例如2/30/2012(并期望抛出)。您可能想要检查无效时间,如23:61。您可能想要检查有效日期,例如您的出生日期。

请查看“正常”案例,边缘案例和错误案例,而不是年度循环。这是单元测试的更好实践。