Spring 测试休眠存储库时,启动不处理 junit 中的提交

Spring boot doesn't process commit in junit when testing hibernate repository

您好,我正在尝试建立一个 junit 测试用例@before setup 但在处理 junit class 之后,我发现我的数据库中没有数据发生变化,也没有异常抛出。有趣的是我可以从控制器调用,它可以通过从 http 客户端调用服务来保存和删除。下面是我的代码,请帮助。非常感谢。

@SpringApplicationConfiguration(classes = MockServletContext.class)
@WebAppConfiguration
public class UserRepositoryTest extends AbstractBestFirstTest {

    private MockMvc mvc;

    @Autowired
    private UserRepositoryI userRepo;

    private void userRepositoryTestPreparer() {
        User user = new User();
        user.setEmail("markII@gmail.com");
        user.setName("Tony Stark");
        userRepo.deleteAll();
        userRepo.save(user);
    }

    @BeforeTransaction
    public void setUpData() {
        userRepositoryTestPreparer();
    }

    @Before
    public void setUp() {
        mvc = MockMvcBuilders.standaloneSetup(new SampleController()).build();
    }

    @After
    public void tearDown() {
        // implement me
    }

    @Transactional
    @Commit
    @Test
    public void testSave() {
        Assert.assertEquals("save failed", 1, userRepo.findUserByName("Tony Stark").size());
        Assert.assertEquals("save failed", 1, userRepo.findUserByEmail("markII@gmail.com").size());
    }

    @Test
    public void testRestfulBasic() throws Exception {
        ResultActions actions = mvc.perform(MockMvcRequestBuilders.get("/sample").accept(MediaType.APPLICATION_JSON));
        actions.andExpect(status().isOk());
        actions.andExpect(content().string(equalTo("Hello World! Greetings from spring boot")));
    }

}

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = BestfirstApplication.class)
public abstract class AbstractBestFirstTest {
    protected Logger logger = LoggerFactory.getLogger(this.getClass());

}

@Transactional
public interface UserRepositoryI extends CrudRepository<User, Long>,UserRepositoryCustomerizedI  {


}

这是我的 pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
<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>com.bestfirst</groupId>
<artifactId>bestfirst</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>bestfirst</name>
<description>Spring Boot project for Best First</description>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
    <retrofit.version>2.0.0-beta3</retrofit.version>
    <org.springframework.version>4.0.2.RELEASE</org.springframework.version>
</properties>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.1.RELEASE</version>
    <relativePath /> <!-- lookup parent from repository -->
</parent>



<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- junit test requires -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <!-- junit test requires -->

    <!-- JPA -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <!-- JPA -->

    <!-- http client retrofit -->
    <dependency>
        <groupId>com.squareup.retrofit2</groupId>
        <artifactId>retrofit</artifactId>
        <version>${retrofit.version}</version>
    </dependency>
    <dependency>
        <groupId>com.squareup.retrofit2</groupId>
        <artifactId>converter-gson</artifactId>
        <version>2.0.0-beta3</version>
    </dependency>
    <!-- http client retrofit -->

    <!-- mysql connector -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!-- mysql connector -->

</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

我最终解决了这个问题。在Spring test senario中,我们必须使用PlatformTransactionManager来处理交易。事实上,我错过了数据库配置中的这一部分。添加到我的配置后,问题消失了!

@Configuration
@EnableTransactionManagement
public class DatabaseConfig {

    @Value("${db.driver}")
    private String DB_DRIVER;

    @Value("${db.password}")
    private String DB_PASSWORD;

    @Value("${db.url}")
    private String DB_URL;

    @Value("${db.username}")
    private String DB_USERNAME;

    @Value("${hibernate.dialect}")
    private String HIBERNATE_DIALECT;

    @Value("${hibernate.show_sql}")
    private String HIBERNATE_SHOW_SQL;

    @Value("${hibernate.hbm2ddl.auto}")
    private String HIBERNATE_HBM2DDL_AUTO;

    @Value("${entitymanager.packagesToScan}")
    private String ENTITYMANAGER_PACKAGES_TO_SCAN;

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(DB_DRIVER);
        dataSource.setUrl(DB_URL);
        dataSource.setUsername(DB_USERNAME);
        dataSource.setPassword(DB_PASSWORD);
        return dataSource;
    }

    @Bean
    public LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
        sessionFactoryBean.setDataSource(dataSource());
        sessionFactoryBean.setPackagesToScan(ENTITYMANAGER_PACKAGES_TO_SCAN);
        Properties hibernateProperties = new Properties();
        hibernateProperties.put("hibernate.dialect", HIBERNATE_DIALECT);
        hibernateProperties.put("hibernate.show_sql", HIBERNATE_SHOW_SQL);
        hibernateProperties.put("hibernate.hbm2ddl.auto", HIBERNATE_HBM2DDL_AUTO);
        sessionFactoryBean.setHibernateProperties(hibernateProperties);

        return sessionFactoryBean;
    }

    @Bean
    public HibernateTransactionManager transactionManager() {
        HibernateTransactionManager transactionManager = new HibernateTransactionManager();
        transactionManager.setSessionFactory(sessionFactory().getObject());
        return transactionManager;
    }

    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);
        return transactionManager;
    }
}

您还可以使用 Rollback(false) 对测试进行注释,请参阅