Quick Expense Manger. Your free expense manager. Lots of features. The application is also ad free.

Integration Test with Spring Boot

Posted on Aug. 4, 2018
integration-test-with-spring-boot

In this article I will show you how to write a Integration test using spring boot. With Integration test we generally want to test the workflow of the application. But it gets difficult to imitate the Production environment while running integration test. I will explain how we can have an in memory database to test the functionality of our application without using the actual database.


For our example, let's say we have a the class Student in our data model as below.


@Entity
@Table(name = "STUDENT_DETAILS")
public class Student {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id_student")
private long id;

@Column(name="name_student")
private String name;
}

And we have the following methods in our Repository.


@Transactional
@Repository
public class StudentRepository {

@PersistenceContext
EntityManager entityManager;

public List<Student> getAllStudents(){
Session session = entityManager.unwrap(Session.class);
Criteria criteria =session.createCriteria(Student.class);
List<Student> students = criteria.list();
return students;

}

public Student getStudentById(long id){
Session session = entityManager.unwrap(Session.class);
Criteria criteria =session.createCriteria(Student.class);
List<Student> students = criteria.add(Restrictions.eq("id",id)).list();
if(students.isEmpty())
return null;
return students.get(0);

}

public Student getStudentByName(String name){
Session session = entityManager.unwrap(Session.class);
Criteria criteria =session.createCriteria(Student.class);
List<Student> students = criteria.add(Restrictions.eq("name",name)).list();
if(students.isEmpty())
return null;
return students.get(0);

}

public void createStudent(Student student){
Session session = entityManager.unwrap(Session.class);
session.save(student);
}

public void updateStudent(Student student){
Session session = entityManager.unwrap(Session.class);
session.update(student);
}

}


And also we have the below controller end points to access the repository methods.


@RestController
public class StudentController {

private StudentRepository studentRepository;
private Environment env;

@Autowired
public StudentController(StudentRepository studentRepository,Environment env){
this.studentRepository = studentRepository;
this.env = env;
}

@RequestMapping(method = RequestMethod.GET,value="/students")
public List<Student> getAllStudents(){
return studentRepository.getAllStudents();
}

@RequestMapping(method = RequestMethod.GET,value="/students/by-id/{id}")
public Student getStudentById(@PathVariable long id){
return studentRepository.getStudentById(id);
}
}

Here the entity Student represents a table STUDENT_DETAILS which has two columns id_student and name_student. The value of id_student is auto incremented whenever a new student is added to the table.


Say we are using a MySQL database to store this student table in our production environment. But for the Integration test, we cannot use that table in the production database.


So, to test the repository methods we will use a in memory database. Suppose we are using a Config Server and Eureka Discovery for our application. So, for our integration test of our component, we will disable these services.


For this, we will create a test profile and create a property file bootstrap-test.properties as shown below. And we will set a in memory database h2.


spring.cloud.config.enabled=false
eureka.client.enabled=false
db.driver=org.h2.Driver
db.url=jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
db.username=sa
db.password=
hibernate.show_sql: true
hibernate.hbm2ddl.auto: create
entitymanager.packagesToScan: com.kaushikbaruah.jmstudentservice
hibernate.dialect = org.hibernate.dialect.H2Dialect

management.security.enabled=false
management.health.db.enabled=false
security.basic.enabled=false
security.stateless=false


You can see that we have disabled the config service and eureka discovery. We have set the in memory h2 database. DB_CLOSE_DELAY=-1 property will keep the connection open while the test is running.


As we are using hibernate, we have set the hibernate dialect for h2. We have disabled spring security as it will ask for authentication while we will try to access our controller end points to execute the repository methods.


Here are the DB configurations for your references which will use the properties that we have set above to initialize the database.


@Configuration
public class ConnectionFactoryBean {

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(Environment env,DataSource dataSource){
LocalContainerEntityManagerFactoryBean entityManagerFactory =
new LocalContainerEntityManagerFactoryBean();
entityManagerFactory.setDataSource(dataSource);

entityManagerFactory.setPackagesToScan(env.getProperty("entitymanager.packagesToScan"));
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
entityManagerFactory.setJpaVendorAdapter(vendorAdapter);

Properties additionalProperties = new Properties();

additionalProperties.put(
"hibernate.dialect",
env.getProperty("hibernate.dialect"));
additionalProperties.put(
"hibernate.show_sql",
env.getProperty("hibernate.show_sql"));
additionalProperties.put(
"hibernate.hbm2ddl.auto",
env.getProperty("hibernate.hbm2ddl.auto"));
entityManagerFactory.setJpaProperties(additionalProperties);

return entityManagerFactory;
}


}
@Configuration
public class DatabaseConfig {

@Bean
public JpaTransactionManager transactionManager(LocalContainerEntityManagerFactoryBean entityManagerFactory){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory.getObject());
return transactionManager;
}

@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();

}
}
@Configuration
public class DataSourceBean {

@Bean
public DataSource dataSource(Environment env){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("db.driver"));
dataSource.setUrl(env.getProperty("db.url"));
dataSource.setUsername(env.getProperty("db.username"));
dataSource.setPassword(env.getProperty("db.password"));
return dataSource;
}

}

Now finally we can write the integration test as show below to test our end points.


@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test")
public class JmStudentServiceApplicationTests {

@Autowired
private TestRestTemplate restTemplate;

@Autowired
private StudentRepository studentRepository;

@Test
public void test() {

Student student = new Student();
student.setId("1");
student.setName("Test Student");

studentRepository.createStudent(student);

assertThat(studentRepository.getStudentById("1").getName().equals("Test Student"));
ResponseEntity<Student> responseEntity = restTemplate.getForEntity("/students/by-id/{id}",Student.class,"1");
assertThat(responseEntity.getBody().getName().equals("Test Student"));

}

}

We have set the Integration test to run on a random port and set the profile as test so that it will use the properties that we have defined in bootstrap-test.properties.


I have just shown you how to test a sample end point. You can extend this to your test requirements. Leave any queries in the comment section.

Sharing is Caring!

Quick Expense Manger. Your free expense manager. Lots of features. The application is also ad free.

GET FREE UPDATES


RECOMMENDED POSTS FOR YOU


profile image

Kaushik Baruah


ABOUT

My name is Kaushik Baruah and I am the chief blogger on this Blog. I have developed this Blog from scratch using Django as the backend and here I like to share my experience as software engineer and research engineer with my online readers. I will try to focus on career planning, latest emerging technologies and tutorials on various computer science subjects. You can follow me on Twitter, Facebook and Google+

GET FREE UPDATES

POPULAR POSTS

Copyright © 2018
About Us

My name is Kaushik Baruah and I am the chief blogger on this Blog. I have developed this Blog from scratch using Django as the backend and here I like to share my experience as software engineer and research engineer with my online readers. I will try to focus on career planning, latest emerging technologies and tutorials on various computer science subjects.

Get Free Updates