如何使用 `when/then` mockito 调用具有相同参数的另一个方法

How to call another method with same arguments using `when/then` mockito

我有以下设置:

class Foo{

    public Foo addDate(String str, Date d){
    .....
    }
    public Foo addString(String str){
    .....
    }
}


class Bar{

    private Foo foo;

    public void bar(){

        foo.addDate(x, x);
    }

}


class testBar{

   //test bar()

}

在为上述用途编写测试用例时,如何在调用 addDate 时使用 when/then 来调用 addString 但使用相同的参数。

是否可以使用 mock 或 spy 这样的东西?

when(foo.addDate("myString", any())).thenReturn(foo.addString("myString"));

您可以使用 thenAnswer,您可以在其中编写一个将 Answer 对象作为参数的 lambda,您可以在其中提取对 addDate:[=15 的调用的参数=]

when(foo.addDate(eq("myString"), any()))
    .thenAnswer(answer -> 
            foo.addString(answer.getArgument(0)));

查看文档 here

When writing a test case for the usage of the above, how can I use when/then to call addString whenever addDate is called but using the same argument.

我不确定你上面的意思,所以我决定用一个工作示例来说明我遇到的情况,评论中是每个测试的系统输出:

public class TestIt {

    @Rule
    public MockitoRule mockitoRule = MockitoJUnit.rule();

    // A bit modified version of your class
    public class Foo {
        public Foo addDate(String str, Date d) {
            System.out.println("addDate(..) should not be called, not mocked?");
            return this; // need to return a Foo :)
        }

        public Foo addString(String str) {
            System.out.println("addString(\"" + str + "\")");
            return this;
        }
    }

    // To call the real method you need the spy so you can mock only
    // methods that needs different functionality 
    @Spy
    private Foo mockFoo;

    // answer that uses param in method invocation
    private Answer<Foo> answer = invocation -> 
            mockFoo.addString(invocation.getArgument(0));
    // answer that calls with fixed param, not using the invocation 
    private Answer<Foo> staticAnswer = invocation -> 
            mockFoo.addString("myString");

    @Test
    public void testAnswer() {
        System.out.println("testAnswer");
        doAnswer(answer).when(mockFoo).addDate(any(String.class), any(Date.class));
        mockFoo.addDate("add me", new Date());
        // testAnswer
        // addString("add me")
    }

    @Test
    public void testStaticAnswer() {
        System.out.println("testStaticAnswer");
        doAnswer(staticAnswer).when(mockFoo).addDate(any(String.class), any(Date.class));
        mockFoo.addDate("add me", new Date());
        // testStaticAnswer
        // addString("myString")        
    }

    @Test
    public void testMyString() { // same as Ruben's answer, only react when myString
        System.out.println("testMyString");
        doAnswer(answer).when(mockFoo).addDate(eq("myString"), any(Date.class));
        mockFoo.addDate("add me", new Date());
        mockFoo.addDate("myString", new Date());
        // testMyString
        // addDate(..) should not be called, not mocked?
        // addString("myString")
    }

}