Java 如何使用变量数据初始化Mock

Java 如何使用变量数据初始化Mock,java,mockito,Java,Mockito,我有这个方法要测试: public static Date getDateSinceUTC(CstOrderBean orderBean) { int year = orderBean.getDeadLineYear(); int month = orderBean.getDeadLineMonth(); int day = orderBean.getDeadLineDay(); int hour = orderBean.getDeadLineHour();

我有这个方法要测试:

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次方法,因此使用许多数据组合设置mock

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

    when(ob.getDeadLineYear()).thenReturn(1, 2, 3);
     ....

循环是个坏主意,不是吗?这样做的正确方法是创建xx个模拟并像那样初始化它们吗?

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

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

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

这可能更简洁,因为您可能应该控制模拟返回的值

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

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

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

这可能更简洁,因为您可能应该控制模拟返回的值

如何模拟取决于要测试的内容。在最后期限上循环可能无法完成您希望它完成的工作

看看闰年是否有效的一个测试可能是:

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是否正常工作。您可能需要一个单独的测试方法来检查无效日期,如2012年2月30日(并期望抛出)。您可能需要检查无效时间,如23:61。您可能需要检查有效日期,如您的生日


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

模拟的方式取决于要测试的内容。在最后期限上循环可能无法完成您希望它完成的工作

看看闰年是否有效的一个测试可能是:

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是否正常工作。您可能需要一个单独的测试方法来检查无效日期,如2012年2月30日(并期望抛出)。您可能需要检查无效时间,如23:61。您可能需要检查有效日期,如您的生日


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

我不能说我理解白盒测试的含义。我想我会通过测试方法一个类似这样填充的模拟“DoThenReturn(1,2,3…100);”并在循环中测试它(1…100)。白盒测试指的是测试人员可以访问实现和接口的情况。当您有一个提供多个结果的mock对象时,您可能会假设在实现中只调用一次mock方法。但是,如果实现发生更改,并且在测试期间多次调用该方法,则测试将中断。在这种情况下,您必须更改测试以反映实现中的更改(白色框),更改实现以反映测试,或者同时更改两者。在任何情况下,实现细节都在接口之外。我明白你的意思,这将是集成测试中的一个问题,这实际上只是一个方法的功能测试,谢谢AleksiI,我不能说我理解你说的白盒测试是什么意思。我想我会通过测试方法一个类似这样填充的模拟“DoThenReturn(1,2,3…100);”并在循环中测试它(1…100)。白盒测试指的是测试人员可以访问实现和接口的情况。当您有一个提供多个结果的mock对象时,您可能会假设在实现中只调用一次mock方法。但是,如果实现发生更改,并且在测试期间多次调用该方法,则测试将中断。在这种情况下,您必须更改测试以反映实现中的更改(白色框),更改实现以反映测试,或者同时更改两者。在任何情况下,实现细节都在接口之外。我明白你的意思,这将是集成测试中的一个问题,这实际上只是一个方法的功能测试,感谢AleksiThanks rajah,但这是一个关于使用mock(一个/多个实例,变量数据)进行测试的一般问题。时间样本只是一个例子。我猜是一个实例,然后返回(1,2,3…1000);是这样做的正确方法感谢rajah,但这是一个关于使用mock(一个/多个实例,变量数据)进行测试的一般性问题。时间样本只是一个例子。我猜是一个实例,然后返回(1,2,3…1000);这样做正确吗