Commit e3e7769f authored by Philip Riecks's avatar Philip Riecks

add current codebase for testcontainers

parent 411597c2
......@@ -3,3 +3,4 @@
## HOWTO's:
* Expose git information with Spring Boot’s Actuator ([Blog](https://rieckpil.de/howto-expose-git-information-with-spring-boots-actuator/), [Sources](https://github.com/rieckpil/blog-tutorials/tree/master/expose-git-information-actuator))
* Write Spring Boot integration tests with a ‘real’ database ([Blog](https://rieckpil.de/howto-write-spring-boot-integration-tests-with-a-real-database/), [Sources](https://github.com/rieckpil/blog-tutorials/tree/master/testcontainers))
......@@ -33,7 +33,15 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<version>1.7.3</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
......
package de.rieckpil.blog.testcontainers;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND)
public class NoPersonFoundException extends RuntimeException {
public NoPersonFoundException(String message) {
super(message);
}
}
package de.rieckpil.blog.testcontainers;
import lombok.Data;
import javax.persistence.*;
@Entity
@Data
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
package de.rieckpil.blog.testcontainers;
import org.springframework.data.jpa.repository.JpaRepository;
public interface PersonRepository extends JpaRepository<Person, Long> {
}
package de.rieckpil.blog.testcontainers;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/persons")
public class PersonsController {
private final PersonRepository personRepository;
public PersonsController(PersonRepository personRepository) {
this.personRepository = personRepository;
}
@GetMapping
public List<Person> getAllPersons() {
return personRepository.findAll();
}
@GetMapping("/{id}")
public Person getPersonById(@PathVariable("id") Long id) {
return personRepository.findById(id).orElseThrow(() -> new NoPersonFoundException("Person with id:" + id +
" not found"));
}
@PostMapping
public Person createNewPerson(@RequestBody Person person) {
Person newPerson = new Person();
newPerson.setName(person.getName());
personRepository.save(newPerson);
return newPerson;
}
@DeleteMapping("/{id}")
public void deletePersonById(@PathVariable("id") Long id) {
personRepository.deleteById(id);
}
}
spring.jpa.hibernate.ddl-auto=
\ No newline at end of file
spring.datasource.url=jdbc:postgresql://localhost:5432/test
spring.datasource.password=postgres
spring.datasource.username=postgres
spring.jpa.hibernate.ddl-auto=validate
spring.flyway.enabled=true
\ No newline at end of file
CREATE TABLE person (
id BIGSERIAL PRIMARY KEY,
name VARCHAR(255)
);
\ No newline at end of file
package de.rieckpil.blog.testcontainers;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
import org.testcontainers.containers.PostgreSQLContainer;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Transactional
public class CreatePersonIntegrationTest {
@ClassRule
public static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer().withPassword("inmemory")
.withUsername("inmemory");
@LocalServerPort
private int localPort;
@Autowired
private PersonRepository personRepository;
public TestRestTemplate testRestTemplate = new TestRestTemplate();
@BeforeClass
public static void beforeClass() {
System.setProperty("spring.datasource.url", postgreSQLContainer.getJdbcUrl());
System.setProperty("spring.datasource.password", postgreSQLContainer.getPassword());
System.setProperty("spring.datasource.username", postgreSQLContainer.getUsername());
}
@Test
public void testRestEndpointForAllPersons() {
Map<String, String> requestParams = new HashMap<String, String>();
Person requestBody = new Person();
requestBody.setName("rieckpil");
assertEquals(0, personRepository.findAll().size());
ResponseEntity<Person> result = testRestTemplate.postForEntity("http://localhost:" + localPort +
"/api/persons", requestBody, Person.class, requestParams);
assertNotNull(result);
assertNotNull(result.getBody().getId());
assertEquals("rieckpil", result.getBody().getName());
assertEquals(1, personRepository.findAll().size());
assertEquals("rieckpil", personRepository.findAll().get(0).getName());
}
}
package de.rieckpil.blog.testcontainers;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
import org.testcontainers.containers.PostgreSQLContainer;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Transactional
public class DeletePersonIntegrationTest {
@ClassRule
public static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer().withPassword("inmemory")
.withUsername("inmemory");
@LocalServerPort
private int localPort;
@Autowired
private PersonRepository personRepository;
public TestRestTemplate testRestTemplate = new TestRestTemplate();
@BeforeClass
public static void beforeClass() {
System.out.println(postgreSQLContainer.getJdbcUrl());
System.setProperty("spring.datasource.url", postgreSQLContainer.getJdbcUrl());
System.setProperty("spring.datasource.password", postgreSQLContainer.getPassword());
System.setProperty("spring.datasource.username", postgreSQLContainer.getUsername());
}
@Test
@Sql("/testdata/FILL_FOUR_PERSONS.sql")
public void testDeletePerson() {
testRestTemplate.delete("http://localhost:" + localPort +
"/api/persons/1");
assertEquals(3, personRepository.findAll().size());
assertFalse(personRepository.findAll().contains("Phil"));
}
}
package de.rieckpil.blog.testcontainers;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
import org.testcontainers.containers.PostgreSQLContainer;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Transactional
public class GetAllPersonsIntegrationTest {
@ClassRule
public static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer().withPassword("inmemory")
.withUsername("inmemory");
@LocalServerPort
private int localPort;
@Autowired
private PersonRepository personRepository;
public TestRestTemplate testRestTemplate = new TestRestTemplate();
@BeforeClass
public static void beforeClass() {
System.out.println(postgreSQLContainer.getJdbcUrl());
System.setProperty("spring.datasource.url", postgreSQLContainer.getJdbcUrl());
System.setProperty("spring.datasource.password", postgreSQLContainer.getPassword());
System.setProperty("spring.datasource.username", postgreSQLContainer.getUsername());
}
@Test
@Sql("/testdata/FILL_FOUR_PERSONS.sql")
public void testGetAllPersons() {
ResponseEntity<Person[]> result = testRestTemplate.getForEntity("http://localhost:" + localPort +
"/api/persons", Person[].class);
List<Person> resultList = Arrays.asList(result.getBody());
assertEquals(4, resultList.size());
assertTrue(resultList.stream().map(p -> p.getName()).collect(Collectors.toList()).containsAll(Arrays.asList
("Mike", "Phil", "Duke", "Tom")));
}
}
package de.rieckpil.blog.testcontainers;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
import org.testcontainers.containers.PostgreSQLContainer;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Transactional
public class GetPersonByIdIntegrationTest {
@ClassRule
public static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer().withPassword("inmemory")
.withUsername("inmemory");
@LocalServerPort
private int localPort;
@Autowired
private PersonRepository personRepository;
public TestRestTemplate testRestTemplate = new TestRestTemplate();
@BeforeClass
public static void beforeClass() {
System.out.println(postgreSQLContainer.getJdbcUrl());
System.setProperty("spring.datasource.url", postgreSQLContainer.getJdbcUrl());
System.setProperty("spring.datasource.password", postgreSQLContainer.getPassword());
System.setProperty("spring.datasource.username", postgreSQLContainer.getUsername());
}
@Test
@Sql("/testdata/FILL_FOUR_PERSONS.sql")
public void testExistingPersonById() {
ResponseEntity<Person> result = testRestTemplate.getForEntity("http://localhost:" + localPort +
"/api/persons/1", Person.class);
assertEquals(HttpStatus.OK, result.getStatusCode());
assertEquals("Phil", result.getBody().getName());
assertEquals(1l, result.getBody().getId().longValue());
}
@Test
public void testNotExistingPersonByIdShouldReturn404() {
personRepository.deleteAll();
ResponseEntity<Person> result = testRestTemplate.getForEntity("http://localhost:" + localPort +
"/api/persons/42", Person.class);
assertEquals(HttpStatus.NOT_FOUND, result.getStatusCode());
assertNull(result.getBody().getName());
assertNull(result.getBody().getId());
}
}
package de.rieckpil.blog.testcontainers;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
import org.testcontainers.containers.PostgreSQLContainer;
@RunWith(SpringRunner.class)
@SpringBootTest
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Transactional
public class TestcontainersApplicationTests {
@ClassRule
public static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer().withPassword("inmemory")
.withUsername("inmemory");
@BeforeClass
public static void beforeClass() {
System.setProperty("spring.datasource.url", postgreSQLContainer.getJdbcUrl());
System.setProperty("spring.datasource.password", postgreSQLContainer.getPassword());
System.setProperty("spring.datasource.username", postgreSQLContainer.getUsername());
}
@Test
public void contextLoads() {
}
......
INSERT INTO person VALUES (1, 'Phil');
INSERT INTO person VALUES (2, 'Mike');
INSERT INTO person VALUES (3, 'Duke');
INSERT INTO person VALUES (4, 'Tom');
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment