当我尝试测试如何触发交易时,它不会回滚。尽管控制台中写的相反。
Beans.xml-包含bean的文件。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">
<context:component-scan base-package="my.app.examples" />
<bean id="clientDAO" class="impl.ClientDAOImpl"/>
<bean id="orderDAO" class="impl.OrderDAOImpl"/>
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" >
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://localhost:5432/postgres1"/>
<property name="username" value="postgres"/>
<property name="password" value="111111"/>
</bean>
</beans>
Pom.xml-具有依赖性的文件。
<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>my.app</groupId>
<artifactId>SpringIntro</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>javax.servlet.jsp.jstl-api</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<version>2.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.12</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<packaging>war</packaging>
<properties>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
</project>
ClientDAOImpl.java-包含代码的文件。
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class ClientDAOImpl implements ClientDAO {
private final Connection conn;
private PreparedStatement st;
private ResultSet rs;
public ClientDAOImpl() throws SQLException, ClassNotFoundException {
this.conn = new PostgresConnection().createConnection();
}
@Override
public User get(final long id) throws SQLException {
User client = null;
this.st = this.conn.prepareStatement("SELECT * FROM CUSTOMERS WHERE sid = ?;");
this.st.setLong(1, id);
this.rs = this.st.executeQuery();
while (this.rs.next()) {
this.rs.getLong("sid");
//some code
client = new User(FIRST_NAME, LAST_NAME, PHONE_NUMBER, EMAIL, CARD_NUMBER,
DELIVERY_ADDRESS, COMMENT);
}
DAO.closing(this.rs, this.st, this.conn);
if (client == null) {
System.out.println("Something wrong with getting client by id - " + id);
} else {
System.out.println("Client with the id = " + id + " successfully retrieved");
}
return client;
}
@Override
public int getRows() throws SQLException, ClassNotFoundException {
this.st = this.conn.prepareStatement("SELECT COUNT(*) AS rowcount FROM CUSTOMERS");
this.rs = this.st.executeQuery();
this.rs.next();
final int count = this.rs.getInt("rowcount");
this.rs.close();
return count;
}
@Override
@Transactional(propagation = Propagation.SUPPORTS, readOnly = false)
public int insert(final User user) throws SQLException, ClassNotFoundException {
this.st = this.conn.prepareStatement(
"INSERT INTO CUSTOMERS(FIRST_NAME,LAST_NAME,PHONE_NUMBER,EMAIL,CARD_NUMBER,DELIVERY_ADDRESS,COMMENT)VALUES(?,?,?,?,?,?,?);");
//some code
final int res = this.st.executeUpdate();
System.out.println("User " + user + " successfully inserted");
return res;
}
}
MainApp.java
@SpringBootApplication
@Configuration
@ImportResource("classpath*:beans.xml")
@EnableJpaRepositories("my.app.repositories")
@EntityScan("my.app.entities")
@EnableTransactionManagement
public class MainApp {
public static void main(final String[] args) {
SpringApplication.run(MainApp.class, args);
}
}
Test.java-具有测试的文件
@ContextConfiguration(classes = Store.class, locations = {"classpath*:beans.xml"})
@RunWith(SpringRunner.class)
@WebMvcTest(MainApp.class)
@Transactional
@Rollback(true)
@TestExecutionListeners({TransactionalTestExecutionListener.class})
public class StoreTest {
private LocalValidatorFactoryBean localValidatorFactory;
@MockBean
HttpRequest request;
HttpRequest response;
@MockBean
private User user;
@Mock
private Model model;
@Autowired
MockMvc mockMvc;
@Mock
Store store;
@Autowired
List<Products> products;
@Before
public void setup() {
this.localValidatorFactory = new LocalValidatorFactoryBean();
this.localValidatorFactory.setProviderClass(HibernateValidator.class);
this.localValidatorFactory.afterPropertiesSet();
MockitoAnnotations.initMocks(this);
final Store store = new Store(this.products);
this.mockMvc = MockMvcBuilders.standaloneSetup(store).build();
}
@Test
@Rollback(true)
public void testForTransaction2() throws ClassNotFoundException, SQLException {
final User user = new User();
user.setFirstName("Ivan");
user.setLastName("Ivanov");
user.setPhoneNumber("18000000");
user.setEmail("mail@gmail.com");
user.setCardNumber("4111111111111111");
user.setDeliveryAddress("address");
user.setComment("comment");
int result = 0;
final ClientDAO clientDao = Mockito.spy(new ClientDAOImpl());
Mockito.when(clientDao.insert(user)).thenThrow(new RuntimeException());
try {
clientDao.insert(user);
} catch (final RuntimeException e) {
System.out.println("Expected failure to trigger transaction caught");
} finally {
result = clientDao.getRows();
}
Assert.assertEquals("it should be equal", 0, result);
}
}
测试完成后,我得到“测试上下文的回滚事务[DefaultTestContext @ 5e4fa1da testClass = StoreTest ...”,但实际上,数据存储在我的postgresql数据库中。可能是什么原因?