Search code examples
javamockitohamcrest

ArgumentCaptor and comparing with hasItems


i am already desperate, i cannot find out why this test is not evaluated as successful. I have checked it milion times:

package someptest;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;
import java.sql.SQLException;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import somep.Order;
import somepBO.BOException;
import somepdao.OrderDAO;

public class XXX {

@Mock
OrderDAO dao;

@Before
public void setup() {
    MockitoAnnotations.initMocks(this);
}

@Test
public void captor_A() throws SQLException, BOException {
    Order order = new Order();
    ArgumentCaptor<Integer> intCaptor = ArgumentCaptor.forClass(Integer.class);
    when(dao.read(any(Integer.class))).thenReturn(order);
    dao.read(123);
    dao.read(456);
    verify(dao, times(2)).read(intCaptor.capture());
    @SuppressWarnings("unused")
    List<Integer> xs = intCaptor.getAllValues();
    assertThat(intCaptor.getAllValues(), hasItems(456));
}
}

Here is a screen from my debugging, captor catches correct values, but assertThat does not accept it, why?

enter image description here


Solution

  • Phew, something seems to go quite wrong on your machine. Based on your test, I created the following self-contained test class:

    import org.junit.Before;
    import org.junit.Test;
    import org.mockito.ArgumentCaptor;
    import org.mockito.Mock;
    import org.mockito.MockitoAnnotations;
    
    import java.util.List;
    
    import static org.hamcrest.CoreMatchers.hasItems;
    import static org.hamcrest.MatcherAssert.assertThat;
    import static org.mockito.ArgumentMatchers.any;
    import static org.mockito.Mockito.*;
    
    public class ArgumentCaptorTest {
    
        private static class Order {
        }
    
        public static class OrderDAO {
            public Order read(Integer any) {
                return null;
            }
        }
    
        @Mock
        OrderDAO dao;
    
        @Before
        public void setup() {
            MockitoAnnotations.initMocks(this);
        }
    
        @Test
        public void captor_A() {
            Order order = new Order();
            ArgumentCaptor<Integer> intCaptor = ArgumentCaptor.forClass(Integer.class);
            when(dao.read(any(Integer.class))).thenReturn(order);
            dao.read(123);
            dao.read(456);
            verify(dao, times(2)).read(intCaptor.capture());
            assertThat(intCaptor.getAllValues(), hasItems(456));
        }
    }
    

    Used dependencies (pom.xml):

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>testing</groupId>
        <artifactId>testing</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <dependencies>
            <dependency>
                <groupId>org.mockito</groupId>
                <artifactId>mockito-core</artifactId>
                <version>2.18.3</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
    </project>
    

    When I start the test, it runs perfectly and gives me a green bar. For what I see, you're doing it right. Maybe you have version conflicts between JUnit, Hamcrest and Mockito that lead to your error? I used these JAR versions:

    • junit:junit:4.12
    • org.hamcrest:hamcrest-core:1.3
    • org.mockito:mockito-core:2.18.3

    I also left the imports so you can compare them with yours (just in case that a "wrong" import causes the error). As you statically import Matchers.* from the Hamcrest package, I am quite sure that this and/or your used library versions cause your problem.