Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 用Mockito测试委托方法_Java_Unit Testing_Mockito - Fatal编程技术网

Java 用Mockito测试委托方法

Java 用Mockito测试委托方法,java,unit-testing,mockito,Java,Unit Testing,Mockito,在下面这样的类中,围绕doActionOne()和doActionTwo()所需的唯一测试是确保它们使用正确的参数委托给doAction() 由于委托doAction(字符串a、int b、boolean c)方法需要大量设置,因此任何解决方案都应该阻止调用实际方法 public class ClassUnderTest { public void doActionOne(String a, int b) { doAction(a, b, true); }

在下面这样的类中,围绕
doActionOne()
doActionTwo()
所需的唯一测试是确保它们使用正确的参数委托给
doAction()

由于委托
doAction(字符串a、int b、boolean c)
方法需要大量设置,因此任何解决方案都应该阻止调用实际方法

public class ClassUnderTest {

    public void doActionOne(String a, int b) {
        doAction(a, b, true);
    }

    public void doActionTwo(String a, int b) {
        doAction(a, b, false);
    }

    public void doAction(String a, int b, boolean c) {
        //already tested
    }
}
这样的测试似乎需要某种局部的模拟或间谍,但我无法做到这一点

虽然这种方法不起作用,但测试应该如下所示

@Test
public void testDoActionOne(){
    ClassUnderTest cut = Mockito.mock(ClassUnderTest.class);

    //call the real method
    when(cut.doActionOne("A1", 1)).thenCallRealMethod();

    //test delegate called with correct params
    verify(cut, times(1)).doAction("A1", 1, true); //fails wanted but not invoked
}
不确定我是否需要这样的东西:


我知道两种方法。一种方法是创建一个匿名内部类,在其中重写不想测试的方法。这不涉及任何莫基托魔法。另一种方法是使用Mockito Spy对象,这是一个真实实例的代理,允许您为某些方法指定存根行为,并让其他方法进入真实实例

方法1,使用匿名内部类:

public class MyTest {

    private String a;
    private String b;
    private boolean c;

    private ClassUnderTest instance = new ClassUnderTest() {
        @Override
        public void doAction(String a, int b, boolean c) {
            MyTest.this.a = a; 
            MyTest.this.b = b;
            MyTest.this.c = c;
        }
    }

    public void test() {
        // SETUP
        String expectedA = "test value A";
        String expectedB = "test value B";
        boolean expectedC = true;

        // CALL
        instance.doActionOne(expectedA, expectedB);

        // VERIFY
        assertEquals(expectedA, a);
        assertEquals(expectedB, b);
        assertEquals(expectedC , c);
    }
方法2,使用Mockito spy对象:

@RunWith(MockitoJUnitRunner.class)
public class MyTest {

    @Spy
    private ClassUnderTest instance;

    public void test() {
        // SETUP
        String expectedA = "test value A";
        String expectedB = "test value B";
        boolean expectedC = true;
        doNothing().when(instance).doAction(expectedA , expectedB, expectedC);

        // CALL
        instance.doActionOne(expectedA, expectedB);

        // VERIFY
        verify(instance, times(1)).doAction(expectedA , expectedB, expectedC);
    }
因为spy是Mockito控制的代理,所以您还可以验证是否对spy调用了方法,这正是您需要的。您还可以为doAction指定一个存根返回值(如果它不是void方法):

事情是这样的:

when(object.getFieldValue(attribute)).thenReturn(NESTED_ID);
verify(object, times(1)).getFieldValue(eq(attribute));

谢谢我曾考虑过使用非Mockito方法,但使用基于Mockito的示例效果很好。对我来说,关键的部分是存根返回值,这样真正的委托方法就不会执行,因为这会导致问题。我的实际代码确实从这些方法中返回了一些东西,所以使用doReturn()就可以了。对于示例问题,我相信委托方法可以使用doNothing()而不是doReturn()来存根,因此可能值得将其添加到答案中。您是对的,我在答案中添加了“doNothing()”存根。
when(object.getFieldValue(attribute)).thenReturn(NESTED_ID);
verify(object, times(1)).getFieldValue(eq(attribute));