1

I'm try testing rest application using spring test.

I have two entity (User, UserInfo) (One-to-one association that assumes both the source and target share the same primary key values.)

This is my testing scenario. (in test code)

  1. Insert temporary user to database using JPA
  2. Request controller using MockMvc perform.
  3. Assert with expected and actual.
  4. Rollback temporary user.

This test case is failed. perhaps to another execution environment(thread) ??

@Test
public void test() throws Exception {
    // create temporary user for test.
    User user = new User();
    user.setType(Type.User);

    UserInfo userInfo = new UserInfo();
    userInfo.setEmail("temporary_user@test.com");
    userInfo.setUser(user);

    user.setUserInfo(userInfo);
    // persist
    userRepository.save(user);

    // request post
    mockMvc.perform(
            post("/user")
            .param("email", "temporary_user@test.com")
            .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.email", userInfo.getEmail()));
}

Is it possible test scenario??

Any help on another solution or how to get my solution working?

This is a sample code.

https://gist.github.com/okihouse/f5e2fe8fa4c17d6a6be9


Solved

I solved this exception.

exception point

  • I used hikariCP. watch sample code.

    @Configuration
    @EnableAutoConfiguration
    @EnableTransactionManagement
    public class JdbcConfig implements TransactionManagementConfigurer {
    
    @Autowired
    private JdbcVO jdbcVO;
    
    @Bean
    public JdbcTemplate jdbcTemplate(){
        return new JdbcTemplate(dataSource());
    }
    
    @Bean
    public DataSource dataSource(){
        final HikariDataSource dataSource = new HikariDataSource();
        dataSource.setDriverClassName(jdbcVO.getDriver());
        dataSource.setJdbcUrl(jdbcVO.getUrl());
        dataSource.setUsername(jdbcVO.getUsername());
        dataSource.setPassword(jdbcVO.getPassword());
        return dataSource;
    }
    
    @Bean
    public PlatformTransactionManager transactionManager(){
        return new DataSourceTransactionManager(dataSource());
    }
    
    @Override
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return transactionManager();
    }
    

    }

Error occured when I used manually datasource configuration.

So, I update datasource configuration in application.yml

spring: 
  jpa:
    database: mysql
    hibernate:
      naming-strategy: org.hibernate.cfg.ImprovedNamingStrategy
    #ddl-auto: create
    properties:
      hibernate.format_sql: true
    show-sql: true

  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/test
    username: test
    password: test

Finally, I shared this code. https://github.com/okihouse/spring-jpa-test

OKIHOUSE
  • 113
  • 7
  • 2
    yes, this kind of test is possible. what do you get ? an exception ? you have no assertion in your testcase – Jérémie B Feb 05 '16 at 07:11
  • I would say not really, because if you use the "standalone" mockmvc, there's no real spring context (no datasource etc) and if you use the other one (the one with a context), you usually don't get access to the repository/data layer. But it's possible to use mocks with the standalone mockmvc and to use a fixed DB (in memory, predefined data) with the other one. See also http://stackoverflow.com/questions/32223490/are-springs-mockmvc-used-for-unit-testing-or-integration-testing –  Feb 05 '16 at 07:12
  • Jérémie B is rigth, this kind of test works, just do it, and do not forgett the @Transactional annotation at your test. – Ralph Feb 05 '16 at 08:32

1 Answers1

0

I would create an in memory database and not mock, you can test things for real. Hibernate will create your database for you.

Example config is below

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:cache="http://www.springframework.org/schema/cache"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
    http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">

    <context:component-scan base-package="net.isban" />
    <tx:annotation-driven />
    <jpa:repositories base-package="net.isban" />

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="org.h2.Driver" />
        <property name="url" value="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1" />
        <property name="username" value="sa" />
        <property name="password" value="" />
    </bean>

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan" value="net.isban.example.entity" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
        </property>
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.hbm2ddl.auto">create</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
            </props>
        </property>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

</beans>
Essex Boy
  • 7,565
  • 2
  • 21
  • 24