Junit中的事务未回滚

时间:2020-07-14 14:12:55

标签: java jdbc junit transactions

当我尝试测试如何触发交易时,它不会回滚。尽管控制台中写的相反。

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数据库中。可能是什么原因?

0 个答案:

没有答案