/** * Copyright 2010-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.mybatis.spring; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.fail; import java.sql.SQLException; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.session.SqlSessionFactory; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeAll; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import com.mockrunner.mock.jdbc.MockConnection; import com.mockrunner.mock.jdbc.MockResultSet; public abstract class AbstractMyBatisSpringTest { protected static PooledMockDataSource dataSource = new PooledMockDataSource(); protected static SqlSessionFactory sqlSessionFactory; protected static ExecutorInterceptor executorInterceptor = new ExecutorInterceptor(); protected static DataSourceTransactionManager txManager; protected static PersistenceExceptionTranslator exceptionTranslator; protected MockConnection connection; protected MockConnection connectionTwo; @BeforeAll public static void setupBase() throws Exception { // create an SqlSessionFactory that will use SpringManagedTransactions SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); factoryBean.setMapperLocations(new Resource[] { new ClassPathResource("org/mybatis/spring/TestMapper.xml") }); // note running without SqlSessionFactoryBean.configLocation set => default configuration factoryBean.setDataSource(dataSource); factoryBean.setPlugins(new Interceptor[] { executorInterceptor }); exceptionTranslator = new MyBatisExceptionTranslator(dataSource, true); sqlSessionFactory = factoryBean.getObject(); txManager = new DataSourceTransactionManager(dataSource); } protected void assertNoCommit() { assertNoCommitJdbc(); assertNoCommitSession(); } protected void assertNoCommitJdbc() { assertThat(connection.getNumberCommits()).as("should not call commit on Connection").isEqualTo(0); assertThat(connection.getNumberRollbacks()).as("should not call rollback on Connection").isEqualTo(0); } protected void assertNoCommitSession() { assertThat(executorInterceptor.getCommitCount()).as("should not call commit on SqlSession").isEqualTo(0); assertThat(executorInterceptor.getRollbackCount()).as("should not call rollback on SqlSession").isEqualTo(0); } protected void assertCommit() { assertCommitJdbc(); assertCommitSession(); } protected void assertCommitJdbc() { assertThat(connection.getNumberCommits()).as("should call commit on Connection").isEqualTo(1); assertThat(connection.getNumberRollbacks()).as("should not call rollback on Connection").isEqualTo(0); } protected void assertCommitSession() { assertThat(executorInterceptor.getCommitCount()).as("should call commit on SqlSession").isEqualTo(1); assertThat(executorInterceptor.getRollbackCount()).as("should not call rollback on SqlSession").isEqualTo(0); } protected void assertRollback() { assertThat(connection.getNumberCommits()).as("should not call commit on Connection").isEqualTo(0); assertThat(connection.getNumberRollbacks()).as("should call rollback on Connection").isEqualTo(1); assertThat(executorInterceptor.getCommitCount()).as("should not call commit on SqlSession").isEqualTo(0); assertThat(executorInterceptor.getRollbackCount()).as("should call rollback on SqlSession").isEqualTo(1); } protected void assertSingleConnection() { assertThat(dataSource.getConnectionCount()).as("should only call DataSource.getConnection() once").isEqualTo(1); } protected void assertExecuteCount(int count) { assertThat(connection.getPreparedStatementResultSetHandler().getExecutedStatements().size()).as( "should have executed %d SQL statements", count).isEqualTo(count); } protected void assertConnectionClosed(MockConnection connection) { try { if ((connection != null) && !connection.isClosed()) { fail("Connection is not closed"); } } catch (SQLException sqle) { fail("cannot call Connection.isClosed() " + sqle.getMessage()); } } protected MockConnection createMockConnection() { // this query must be the same as the query in TestMapper.xml MockResultSet rs = new MockResultSet("SELECT 1"); rs.addRow(new Object[] { 1 }); MockConnection con = new MockConnection(); con.getPreparedStatementResultSetHandler().prepareResultSet("SELECT 1", rs); return con; } /* * Setup a new Connection before each test since its closed state will need to be checked * afterwards and there is no Connection.open(). */ @BeforeEach public void setupConnection() throws SQLException { dataSource.reset(); connection = createMockConnection(); connectionTwo = createMockConnection(); dataSource.addConnection(connectionTwo); dataSource.addConnection(connection); } @BeforeEach public void resetExecutorInterceptor() { executorInterceptor.reset(); } @AfterEach public void validateConnectionClosed() { assertConnectionClosed(connection); connection = null; } }