laihonghui / spring-testing

A Spring Boot application with lots of sample tests

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Testing Microservices in Spring

This repository contains a Spring Boot application with lots of exemplary tests on different levels of the Test Pyramid. It shows an opinionated way to thoroughly test your spring application by demonstrating different types and levels of testing. You will find that some of the tests are duplicated along the test pyramid -- concepts that have already been tested in lower-level tests will be tested in more high-level tests. This contradicts the premise of the test pyramid. In this case it helps showcasing different kinds of tests which is the main goal of this repository.

Application Architecture

 ╭┄┄┄┄┄┄┄╮      ┌──────────┐      ┌──────────┐
 ┆   ☁   ┆  ←→  │    ☕     │  ←→  │    💾    │
 ┆  Web  ┆ HTTP │  Spring  │      │ Database │
 ╰┄┄┄┄┄┄┄╯      │  Service │      └──────────┘
                └──────────┘
                     ↑ JSON/HTTP
                     ↓
                ┌──────────┐
                │    ☁     │
                │ Weather  │
                │   API    │
                └──────────┘

The sample application is almost as easy as it gets. It stores Persons in an in-memory database (using Spring Data) and provides a REST interface with three endpoints:

  • GET /hello: Returns "Hello World!". Always.
  • GET /hello/{lastname}: Looks up the person with lastname as its last name and returns "Hello {Firstname} {Lastname}" if that person is found.
  • GET /weather: Calls a downstream weather API via HTTP and returns a summary for the current weather conditions in Hamburg, Germany

Internal Architecture

The Spring Service itself has a pretty common internal architecture:

  • Controller classes provide REST endpoints and deal with HTTP requests and responses
  • Repository classes interface with the database and take care of writing and reading data to/from persistent storage
  • Client classes talk to other APIs, in our case it fetches JSON via HTTP from the darksky.net weather API
Request  ┌─────────────────────────────────────┐
 ─────────→ ┌─────────────┐    ┌─────────────┐ │   ┌─────────────┐
 ←───────── │  Controller │ ←→ │  Repository │←──→ │  Database   │
Response │  └─────────────┘    └─────────────┘ │   └─────────────┘
         │         ↓                           │
         │    ┌──────────┐                     │
         │    │  Client  │                     │
         │    └──────────┘                     │
         └─────────│───────────────────────────┘
                   │
                   ↓   
              ┌──────────┐
              │    ☁     │
              │ Weather  │
              │   API    │
              └──────────┘

Test Layers

                ┌──────────┐
                │    ☁     │
                │ Weather  │
                │   API    │
                └──────────┘
                     ↑
                     ↓
 ╭┄┄┄┄┄┄┄╮      ┌──────────┐      ┌──────────┐
 ┆   ☁   ┆  ←→  │    ☕     │  ←→  │    💾    │
 ┆  Web  ┆      │  Spring  │      │ Database │
 ╰┄┄┄┄┄┄┄╯      │  Service │      └──────────┘
                └──────────┘

  │        HTTP       │      Database        │
  └─── Integration ───┴──── Integration ─────┘

  │                                          │
  └────────────── Acceptance ────────────────┘               

Tools

You can find lots of different tools, frameworks and libraries being used in the different examples:

  • Spring Boot: application framework
  • JUnit: test runner
  • Hamcrest Matchers: assertions
  • Mockito: test doubles (mocks, stubs)
  • RestAssured: testing the service end to end via HTTP
  • Wiremock: provide HTTP stubs for downstream services

Get started

In order to run the service, you need to set the WEATHER_API_KEY environment variable to a valid API key retrieved from darksky.net.

A simple way is to rename the env.sample file to .env, fill in your API key from darksky.net and source it before running your application:

source .env

Once you've provided the API key you can run the application using

./gradlew bootRun

The application will start on port 8080 so you can send a sample request to http://localhost:8080/hello to see if you're up and running.

About

A Spring Boot application with lots of sample tests


Languages

Language:Java 99.3%Language:Shell 0.7%