This document discusses integration testing for microservices using Spring Boot. It covers: 1) the complexities of testing microservice architectures, 2) the anatomy of a microservice, and 3) an effective approach using Spring Boot to implement unit, integration, and component tests. Integration tests with Spring Boot can verify service integration with external dependencies like databases and APIs. Component tests isolate services by mocking external dependencies with tools like WireMock. Additional levels of testing are needed for microservices, and integration testing with containers provides benefits like reliability, configurability and speed.
2. 2
WHAT I WILL COVER?
1) Microservices architecture and it’s testing complexities
2) Anatomy of microservice
3) Effective integration testing with Spring Boot
4) Component tests with spring-boot-test-containers
5) Conclusions
3. 3
WHO AM I
6+ years as Test Automation Engineer
Worked with Java / C# web applications
/ backend systems from CMS to enterprise
Working now as QA Automation Lead
at Playtika
7. 7
MICROSERVICES TEST AUTOMATION APPROACH
End – to – End (UI / API) tests
Contract
tests
Component
tests
Integration
tests
Unit tests
Component
tests
Integration
tests
Unit tests
10. 10
UNIT TESTS
• Verify state or behavior of unit of code within
one single microservice
• Use stubbing / mocking
Component
tests
Integration
tests
Unit tests
11. 11
INTEGRATION TESTS
Verify service integration logic with various
external sources
- persistence: MariaDB, Couchbase,
Aerospike, Neo4j, etc)
- gateway: HTTP REST API,
Message Queues, RPC, etc.
Component
tests
Integration
tests
Unit tests
12. 12
INTEGRATION TESTS
Spring Boot “arsenal”:
o @DataJpaTest
o @DataMongoTest
o @JdbcTest
o @DataRedisTest
o @DataNeo4jTest
Microservice
Persistence
16. 16
WRITING SIMPLE SQL DB TEST
@Autowired
private TestEntityManager testEntityManager;
@Autowired
private MachineSettingRepository machineSettingRepository;
17. 17
WRITING SIMPLE TEST FOR SQL DB
@Test
public void shouldFindSingleMachineSetting() throws Exception {
MachineSettingEntity settingEntity = new MachineSettingEntity(1,
“Test”);
testEntityManager.persistAndFlush(settingEntity);
assertThat(machineSettingRepository.findAll().filter(e ->
e.getMachineId() == settingEntity.getMachineId())
.collect(Collectors.toList()).get(0)).isEqualTo(settingEntity)
.withFailMessage("Unable to find machine setting with id " +
settingEntity.getMachineId());
}
18. 18
RUNNING SQL DB TEST
@RunWith(SpringRunner.class)
@ActiveProfiles("test")
@DataJpaTest
@AutoConfigureTestDatabase(replace =
AutoConfigureTestDatabase.Replace.NONE)
@TestPropertySource(properties =
{"embedded.couchbase.enabled=false"}
public class MachineSettingDatabaseIntegrationTest
19. 19
WRITING SIMPLE TEST FOR NOSQL DB
@Autowired
private MachineStateDocumentRepository machineStateDocumentRepository;
@Test
public void shouldFindStateInDb() {
MachineStateDocument testState = MachineStateDocument.builder()
.key("4-4")
.build();
machineStateDocumentRepository.save(testState);
assertThat(machineStateDocumentRepository.findOne("4-4").get())
.isEqualTo(testState)
.withFailMessage("Unable to find state by key: " + testState.getKey());
}
20. 20
RUNNING NOSQL DB TEST
@RunWith(SpringRunner.class)
@ActiveProfiles("test")
@SpringBootTest(classes = {MachineStateTestConfiguration.class})
public class MachineStateDatabaseIntegrationTest
21. 21
ADDITIONAL CONFIGURATIONS
@EnableAutoConfiguration(exclude = {
DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
LiquibaseAutoConfiguration.class,
XADataSourceAutoConfiguration.class})
@TestConfiguration
@Profile("test")
@Import({CouchbaseConfiguration.class})
public class MachineStateTestConfiguration
26. 26
RUNNING TEST FOR CONTROLLER
@RunWith(SpringRunner.class)
@WebMvcTest(MachineStateController.class)
@ActiveProfiles("test")
@TestPropertySource(properties
={"embedded.couchbase.enabled=false",
"embedded.mariadb.enabled=false"})
public class MachineStateControllerIntegrationTest
30. 30
SETTING UP COMPONENT TEST
public abstract class MachineBaseComponentTest {
@ClassRule
public static final WireMockClassRule externalApi = new
WireMockClassRule(7070);
@Autowired
protected WebApplicationContext context;
protected MockMvc mvc;
@Before
public void setUp() {
mvc = MockMvcBuilders.webAppContextSetup(context).build();
}
}
31. 31
COMPONENT TEST
@Test
public void shouldReturnMachineStateWhenStateIsInRepository() throws
Exception {
mvc.perform(get("/machine?userId=1"))
.andExpect(status().is(200))
.andExpect(jsonPath("$.data.machineId").value("1"))
.andExpect(jsonPath("$.data.machineAvailable").value("true"));
}