独立运行的Mockito可以运行,但是一起运行时会失败

时间:2019-06-01 18:28:15

标签: mockito

我正在模拟jdbc连接,结果集和PreparedStatment。

因此,当运行测试一个接一个地工作时。但是,如果运行类中的所有测试,则方法whenSelectB将失败。

java.lang.AssertionError: There are 2 rows
Expected: <2>
     but: was <0>
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
    at net.sf.jkniv.whinstone.jdbc.dml.MockitoSample.whenSelectB(MockitoSample.java:155)

有一些技巧可以运行吗?

public class MockitoSample
{        
    private DataSource        dataSource;
    private Connection        connection;
    private PreparedStatement stmt;
    private ResultSet         rs;
    private ResultSetMetaData rsMetadata;
    private DatabaseMetaData  dbMetadata;

    private RepositoryConfig  repositoryConfig;
    private SqlContext        sqlContext;
    private Selectable        sql;

    @Before
    public void setUp() throws SQLException
    {
        this.connection = mock(Connection.class);
        this.dataSource = mock(DataSource.class);
        this.stmt = mock(PreparedStatement.class);
        this.rs = mock(ResultSet.class);
        this.rsMetadata = mock(ResultSetMetaData.class);
        this.dbMetadata = mock(DatabaseMetaData.class);
        this.repositoryConfig = mock(RepositoryConfig.class);
        this.sqlContext = mock(SqlContext.class);
        this.sql = mock(Selectable.class);

        given(this.dataSource.getConnection()).willReturn(this.connection);
        given(this.connection.prepareStatement(anyString(), anyInt(), anyInt())).willReturn(this.stmt);
        given(this.stmt.executeQuery()).willReturn(this.rs);
        given(this.stmt.executeQuery(anyString())).willReturn(this.rs);
        given(this.dbMetadata.getJDBCMajorVersion()).willReturn(1);
        given(this.dbMetadata.getJDBCMinorVersion()).willReturn(0);
        given(this.dbMetadata.getDriverName()).willReturn("MOCKITO");
        given(this.dbMetadata.getDriverVersion()).willReturn("1");

        given(this.rs.getMetaData()).willReturn(this.rsMetadata);

        given(this.repositoryConfig.getName()).willReturn("Mockito");
        given(this.repositoryConfig.lookup()).willReturn(this.dataSource);
        given(this.repositoryConfig.getJndiDataSource()).willReturn("jdbc/Mockito");
        given(this.repositoryConfig.getProperty(RepositoryProperty.JDBC_ADAPTER_FACTORY.key()))
                .willReturn(DataSourceAdapter.class.getName());
        given(this.repositoryConfig.getTransactionType()).willReturn(TransactionType.LOCAL);
        given(this.repositoryConfig.getQueryNameStrategy()).willReturn("net.sf.jkniv.sqlegance.HashQueryNameStrategy");

        given(this.sql.getValidateType()).willReturn(ValidateType.NONE);
        given(this.sql.getSql(any())).willReturn("select * from dual");
        given(this.sql.getSqlDialect()).willReturn(new AnsiDialect());
        given(this.sql.getParamParser()).willReturn(ParamParserFactory.getInstance(ParamMarkType.COLON));
        given(this.sql.getStats()).willReturn(NoSqlStats.getInstance());
        given(this.sql.getSqlType()).willReturn(SqlType.SELECT);
        given(this.sql.asSelectable()).willReturn((Selectable) this.sql);

        given(this.sqlContext.getRepositoryConfig()).willReturn(this.repositoryConfig);
        given(this.sqlContext.getQuery(anyString())).willReturn(this.sql);

    }

    @Test
    public void whenSelectA() throws SQLException
    {
        Repository repository = RepositoryService.getInstance().lookup(RepositoryType.JDBC).newInstance(sqlContext);
        given(this.rsMetadata.getColumnCount()).willReturn(2);
        given(this.rsMetadata.getColumnLabel(1)).willReturn("id");
        given(this.rsMetadata.getColumnName(1)).willReturn("id");
        given(this.rsMetadata.getColumnLabel(2)).willReturn("name");
        given(this.rsMetadata.getColumnName(2)).willReturn("name");
        given(this.rs.getMetaData()).willReturn(this.rsMetadata);
        given(this.sql.getReturnType()).willReturn(FlatBook.class.getName());
        doReturn(FlatBook.class).when(this.sql).getReturnTypeAsClass();
        given(rs.next()).willReturn(true, true, false);
        given(rs.getObject(1)).willReturn(1001L, 1002L);
        given(rs.getObject(2)).willReturn("Beyond Good and Evil", "The Rebel: An Essay on Man in Revolt");

        Queryable q = QueryFactory.of("2 FlatBook");
        List<FlatBook> books = repository.list(q);
        assertThat("There are 2 rows", books.size(), equalTo(2));
        assertThat("Row is a FlatBook object", books.get(0), instanceOf(FlatBook.class));
        for (FlatBook b : books)
        {
            assertThat(b.getId(), notNullValue());
            assertThat(b.getName(), notNullValue());
        }
    }

    @Test
    public void whenSelectB() throws SQLException
    {
        Repository repository = RepositoryService.getInstance().lookup(RepositoryType.JDBC).newInstance(sqlContext);
        given(rsMetadata.getColumnCount()).willReturn(2);
        given(this.rsMetadata.getColumnLabel(1)).willReturn("id");
        given(this.rsMetadata.getColumnName(1)).willReturn("id");
        given(this.rsMetadata.getColumnLabel(2)).willReturn("name");
        given(this.rsMetadata.getColumnName(2)).willReturn("name");
        given(this.rs.getMetaData()).willReturn(this.rsMetadata);
        given(this.sql.getReturnType()).willReturn(FlatAuthor.class.getName());
        doReturn(FlatAuthor.class).when(this.sql).getReturnTypeAsClass();
        given(rs.next()).willReturn(true, true, false);
        given(rs.getObject(1)).willReturn(1L, 2L);
        given(rs.getObject(2)).willReturn("Author 1", "Author 2");

        Queryable q = QueryFactory.of("2 FlatAuthor");
        List<FlatAuthor> books = repository.list(q);
        assertThat("There are 2 rows", books.size(), equalTo(2));
        assertThat("Row is a FlatAuthor object", books.get(0), instanceOf(FlatAuthor.class));
        for (FlatAuthor a : books)
        {
            assertThat(a.getId(), notNullValue());
            assertThat(a.getName(), notNullValue());
        }
        verify(rs).close();
        verify(stmt).close();
        verify(connection, atLeast(1)).close();
    }   

该错误发生在Repository实例内部,它使用rs.next ()(ResultSet)方法,但在应返回两次false时返回true

1 个答案:

答案 0 :(得分:0)

我的Repository实例在DataSouce中拥有ThreadLocal类,因此,当whenSelectB尝试获取新的Mock时,它将检索旧的DataSource,该数据源又检索了旧的Connection,后者又得到了旧的Connection。检索旧的ResultSet的语句。换句话说,我在测试之间有一个肮脏的环境。存储库必须在事务开始时才保持连接。

感谢@ Joakim-Danielson和@Antoniossss