如何在同一测试中使用2个不同的参数captor类

时间:2016-12-15 01:42:24

标签: java testing mocking mockito dao

我的主类包含1个int类型和4个字符串。 我想测试一个数据库的插入函数。在下面的代码中,它继续失败" junit.framework.AssertionFailedError"。 将原始类中的数据类型切换为5个字符串并对其进行测试,效果很好。所以我认为这可能是由于存在2个不同的ArgumentCaptor类。

@Test
public void HappyTest2() throws SQLException, DAOException{
    when(conn.prepareStatement(anyString())).thenReturn(psmt);
    ArgumentCaptor<Integer> integercaptor = ArgumentCaptor.forClass(Integer.class);
    ArgumentCaptor<String> Stringcaptor = ArgumentCaptor.forClass(String.class);

    Product p = new Product(1);
    p.setType("myType");
    p.setManufacturer("myManufacturer");
    p.setProductionDate("myProductionDate");
    p.setExpiryDate("myExpiryDate");

    testingDAO.insertProduct(p);
    verify(psmt, times(1)).setInt(anyInt(), integercaptor.capture());
    Assert.assertTrue(integercaptor.getAllValues().get(0).equals(1));
    verify(psmt, times(4)).setString(anyInt(), Stringcaptor.capture());
    Assert.assertTrue(Stringcaptor.getAllValues().get(1).equals("myType"));
    Assert.assertTrue(Stringcaptor.getAllValues().get(2).equals("myManufacturer"));
    Assert.assertTrue(Stringcaptor.getAllValues().get(3).equals("myProductionDate"));
    Assert.assertTrue(Stringcaptor.getAllValues().get(4).equals("myExpiryDate"));
}

1 个答案:

答案 0 :(得分:1)

我创建了一个单元测试来模拟你的场景(改变了一些东西使其工作,即添加了一个数据源...)我注意到你在访问ArgumentCaptor值时使用的是基于1的编号 - 当我改为0基础,测试通过。不知道这是否是您的问题的根本原因,但这是我的测试的源代码:

package com.test;

import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import javax.sql.DataSource;

public class DaoTest {

    @SuppressWarnings("serial")
    public static class DAOException extends Exception {
    }

    public static class Product {

        private final Integer number;
        private String type;
        private String manufacturer;
        private String productionDate;
        private String expiryDate;

        public Product(Integer number) {
            this.number = number;
        }

        public Integer getNumber() {
            return number;
        }

        public String getType() {
            return type;
        }

        public String getManufacturer() {
            return manufacturer;
        }

        public String getProductionDate() {
            return productionDate;
        }

        public String getExpiryDate() {
            return expiryDate;
        }

        public void setType(String type) {
            this.type = type;
        }

        public void setManufacturer(String manufacturer) {
            this.manufacturer = manufacturer;
        }

        public void setProductionDate(String productionDate) {
            this.productionDate = productionDate;
        }

        public void setExpiryDate(String expiryDate) {
            this.expiryDate = expiryDate;
        }
    }

    public static class Dao {

        private DataSource ds;

        public Dao(DataSource ds) {
            this.ds = ds;
        }

        public void insertProduct(Product p) throws SQLException {
            Connection conn = ds.getConnection();
            PreparedStatement psmt =
                    conn.prepareStatement("SELECT * FROM foo WHERE a = ? AND b = ? AND c = ? AND d = ? AND e = ?");
            psmt.setInt(1, p.getNumber());
            psmt.setString(2, p.getType());
            psmt.setString(3, p.getManufacturer());
            psmt.setString(4, p.getProductionDate());
            psmt.setString(5, p.getExpiryDate());

            // other code here to execute the psmt etc.....
        }
    }

    private DataSource ds = Mockito.mock(DataSource.class);
    private Connection conn = Mockito.mock(Connection.class);
    private PreparedStatement psmt = Mockito.mock(PreparedStatement.class);
    private Dao testingDAO = new Dao(ds);

    @Test
    public void HappyTest2() throws SQLException, DAOException {
        when(ds.getConnection()).thenReturn(conn);
        when(conn.prepareStatement(anyString())).thenReturn(psmt);
        ArgumentCaptor<Integer> integerCaptor = ArgumentCaptor.forClass(Integer.class);
        ArgumentCaptor<String> stringCaptor = ArgumentCaptor.forClass(String.class);

        Product p = new Product(1);
        p.setType("myType");
        p.setManufacturer("myManufacturer");
        p.setProductionDate("myProductionDate");
        p.setExpiryDate("myExpiryDate");

        testingDAO.insertProduct(p);

        verify(psmt, times(1)).setInt(anyInt(), integerCaptor.capture());
        assertTrue(integerCaptor.getAllValues().get(0).equals(1));

        verify(psmt, times(4)).setString(anyInt(), stringCaptor.capture());

        // 0 based index
        assertTrue(stringCaptor.getAllValues().get(0).equals("myType"));
        assertTrue(stringCaptor.getAllValues().get(1).equals("myManufacturer"));
        assertTrue(stringCaptor.getAllValues().get(2).equals("myProductionDate"));
        assertTrue(stringCaptor.getAllValues().get(3).equals("myExpiryDate"));
    }
}

我没有使用任何mockito注释,更喜欢从依赖注入的角度来保持简单。