Java – mockito capture does not maintain a list of captures when capturing

In mockito, we encounter a situation where the capture of the list does not return the expected results Test case:

>We add pip to the list > we capture the list > we add Sok to the list

In our assertion, we only expect "PIP" to be there, but "Sok" is also there We think this is incorrect because "Sok" is not in the list at the time of capture

java. Lang. assertionerror: expected: [PIP] actual: [pip, Sok]

>Does anyone have a solution? > Is this an error in mockito or a function? > Why does mockito keep a reference to the list instead of copying the list for a capture time?

The following are test cases:

@RunWith(MockitoJUnitRunner.class)
public class CaptureTest {

    @Captor
    private ArgumentCaptor<List> listCapture;

    @Mock
    private ListPrinter listPrinter;

    private TestClass testClass;

    @Before
    public void setUp() {
        testClass = new TestClass(listPrinter);
    }

    @Test
    public void testCapture() {
        testClass.simulateFailSituation();
        verify(listPrinter).printList(listCapture.capture());
        // THIS FAILS: Expected:[Pip],Actual:[Pip,Sok]
        assertEquals(Collections.singletonList("Pip"),listCapture.getValue());
    }

    public class TestClass {

        private List list = new ArrayList();
        private ListPrinter listPrinter;

        public TestClass(ListPrinter listPrinter) {
            this.listPrinter = listPrinter;
        }

        private void simulateFailSituation() {
            list.add("Pip");
            listPrinter.printList(list);
            list.add("Sok");
        }
    }

    public interface ListPrinter {
        void printList(List list);
    }
  }

Solution

This may sound like an amazing feature, but then think: if it's copying, where should it stop? You may catch some objects that have many references to other objects, and eventually you may make deep copies of almost all objects in the JVM instance

This will be a serious performance hit, so I kind of understand why

Therefore, you can choose two methods:

>Use immutable objects where applicable In addition to being easier to test, it also makes the code easier to read and debug. > Test the value immediately during a call instead of capturing the reference value For void methods, you can use the doanswer method with answer < void >, where you can test or copy By the way, this is new. See how to make mock to void methods with mockito

I find it more powerful than verification In your case, doanswer looks like this:

doAnswer(invocation -> {
    assertEquals(Collections.singletonList("Pip"),invocation.getArguments()[0]);
    return null;
}).when(listPrinter).printList(Matchers.anyList());
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>