├── .gitignore
├── CHEATSHEET.md
├── non-reactive
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── car
│ │ │ ├── CarsApplication.java
│ │ │ ├── domain
│ │ │ ├── Car.java
│ │ │ └── CarRepository.java
│ │ │ ├── service
│ │ │ └── CarService.java
│ │ │ └── web
│ │ │ ├── CarNotFoundException.java
│ │ │ └── CarsController.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── com
│ └── example
│ └── car
│ ├── CachingTest.java
│ ├── IntegrationTests.java
│ ├── domain
│ └── CarRepositoryTests.java
│ ├── service
│ └── CarServiceTest.java
│ └── web
│ └── CarsControllerTests.java
└── reactive
├── main
├── java
│ └── com
│ │ └── example
│ │ └── car
│ │ ├── CarsApplication.java
│ │ ├── domain
│ │ ├── Car.java
│ │ └── CarRepository.java
│ │ └── web
│ │ └── CarController.java
└── resources
│ └── application.properties
├── pom.xml
└── test
└── java
└── com
└── example
└── car
├── IntegrationTests.java
├── domain
└── CarRepositoryTests.java
└── web
└── CarControllerTests.java
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 |
12 | ### IntelliJ IDEA ###
13 | .idea
14 | *.iws
15 | *.iml
16 | *.ipr
17 |
18 | ### NetBeans ###
19 | nbproject/private/
20 | build/
21 | nbbuild/
22 | dist/
23 | nbdist/
24 | .nb-gradle/
--------------------------------------------------------------------------------
/CHEATSHEET.md:
--------------------------------------------------------------------------------
1 | ## Annotations
2 |
3 | | Annotation | Description
4 | |------------------------------- |--------------
5 | |@RunWith(SpringRunner.class) | @SpringJUnit4ClassRunner alias; add for junit test support
6 | | |
7 | |@SpringBootTest | Bootstrap test with SpringBoot support, load application.properties;
8 | | | specify random or specific port to start app; TestRestTemplate bean made available;
9 | | |
10 | |@WebMvcTest | Use in combination with SpringRunner to load context relevant spring mvc components
11 | | |
12 | |@RunWith(MockitoJUnitRunner.class) | Initializes mocks so no need to initMocks(this); automatic validation of framework usage
13 | | |
14 | |@DataJpaTest | Loads jpa relevant config; uses in-memory db by default, override with @AutoConfigureTestDatabase
15 | | |
16 | |@AutoConfigureTestDatabase | If you do not want to use auto-configured test database, use this to configure a test db
17 | | |
18 | |@MockBean | Use with SpringRunner class to mock components in test
19 | | |
20 | |@Mock | Similar to @MockBean but without spring support; use with MockitoJUnitRunner
21 | | |
22 | |@AutoConfigureMockMvc | More control of mock-mvc, disable spring security bits etc
23 | | |
24 | |@WebFluxTest | Use in combination with SpringRunner to load context relevant spring WebFlux components
25 | | |
26 | |@DataMongoTest | Use in combination with SpringRunner for testing MongoDB components; uses in-memory MongoDB by default
27 |
--------------------------------------------------------------------------------
/non-reactive/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.example
7 | mbhave-tdd-demo
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | non-reactive-tdd-demo
12 | Demo project for TDD with Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.0.0.BUILD-SNAPSHOT
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 1.8
25 |
26 |
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-starter-web
31 |
32 |
33 | org.springframework.boot
34 | spring-boot-starter-data-jpa
35 |
36 |
37 | mysql
38 | mysql-connector-java
39 |
40 |
41 | com.h2database
42 | h2
43 | test
44 |
45 |
46 | org.springframework.boot
47 | spring-boot-starter-test
48 | test
49 |
50 |
51 |
52 |
53 |
54 |
55 | org.springframework.boot
56 | spring-boot-maven-plugin
57 |
58 |
59 |
60 |
61 |
62 |
63 | spring-snapshots
64 | Spring Snapshots
65 | https://repo.spring.io/snapshot
66 |
67 | true
68 |
69 |
70 |
71 | spring-milestones
72 | Spring Milestones
73 | https://repo.spring.io/milestone
74 |
75 | false
76 |
77 |
78 |
79 |
80 |
81 |
82 | spring-snapshots
83 | Spring Snapshots
84 | https://repo.spring.io/snapshot
85 |
86 | true
87 |
88 |
89 |
90 | spring-milestones
91 | Spring Milestones
92 | https://repo.spring.io/milestone
93 |
94 | false
95 |
96 |
97 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/non-reactive/src/main/java/com/example/car/CarsApplication.java:
--------------------------------------------------------------------------------
1 | package com.example.car;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cache.annotation.EnableCaching;
6 |
7 | @SpringBootApplication
8 | @EnableCaching
9 | public class CarsApplication {
10 |
11 | public static void main(String[] args) {
12 | SpringApplication.run(CarsApplication.class, args);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/non-reactive/src/main/java/com/example/car/domain/Car.java:
--------------------------------------------------------------------------------
1 | package com.example.car.domain;
2 |
3 | import javax.persistence.Entity;
4 | import javax.persistence.GeneratedValue;
5 | import javax.persistence.Id;
6 |
7 | @Entity
8 | public class Car {
9 |
10 | @Id
11 | @GeneratedValue
12 | private Long id;
13 |
14 | private String name;
15 |
16 | private String type;
17 |
18 | public Car(String name, String type) {
19 | this.name = name;
20 | this.type = type;
21 | }
22 |
23 | public String getName() {
24 | return this.name;
25 | }
26 |
27 | public void setName(String name) {
28 | this.name = name;
29 | }
30 |
31 | public String getType() {
32 | return this.type;
33 | }
34 |
35 | public void setType(String type) {
36 | this.type = type;
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/non-reactive/src/main/java/com/example/car/domain/CarRepository.java:
--------------------------------------------------------------------------------
1 | package com.example.car.domain;
2 |
3 | import org.springframework.data.repository.CrudRepository;
4 |
5 | public interface CarRepository extends CrudRepository {
6 |
7 | Car findByName(String name);
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/non-reactive/src/main/java/com/example/car/service/CarService.java:
--------------------------------------------------------------------------------
1 | package com.example.car.service;
2 |
3 | import com.example.car.domain.Car;
4 | import com.example.car.domain.CarRepository;
5 | import com.example.car.web.CarNotFoundException;
6 |
7 | import org.springframework.cache.annotation.Cacheable;
8 | import org.springframework.stereotype.Service;
9 |
10 | @Service
11 | public class CarService {
12 |
13 | private CarRepository carRepository;
14 |
15 | public CarService(CarRepository carRepository) {
16 | this.carRepository = carRepository;
17 | }
18 |
19 | @Cacheable("cars")
20 | public Car getCarDetails(String name) {
21 | Car car = carRepository.findByName(name);
22 | if(car == null) {
23 | throw new CarNotFoundException();
24 | }
25 | return car;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/non-reactive/src/main/java/com/example/car/web/CarNotFoundException.java:
--------------------------------------------------------------------------------
1 | package com.example.car.web;
2 |
3 | import org.springframework.http.HttpStatus;
4 | import org.springframework.web.bind.annotation.ResponseStatus;
5 |
6 | @ResponseStatus(HttpStatus.NOT_FOUND)
7 | public class CarNotFoundException extends RuntimeException {
8 | }
9 |
--------------------------------------------------------------------------------
/non-reactive/src/main/java/com/example/car/web/CarsController.java:
--------------------------------------------------------------------------------
1 | package com.example.car.web;
2 |
3 | import com.example.car.domain.Car;
4 | import com.example.car.service.CarService;
5 |
6 | import org.springframework.web.bind.annotation.GetMapping;
7 | import org.springframework.web.bind.annotation.PathVariable;
8 | import org.springframework.web.bind.annotation.RestController;
9 |
10 | @RestController
11 | public class CarsController {
12 |
13 | private final CarService carService;
14 |
15 | public CarsController(CarService carService) {
16 | this.carService = carService;
17 | }
18 |
19 | @GetMapping("/cars/{name}")
20 | public Car getCar(@PathVariable String name) {
21 | Car car = this.carService.getCarDetails(name);
22 | if (car == null) {
23 | throw new CarNotFoundException();
24 | }
25 | return car;
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/non-reactive/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.datasource.url=jdbc:mysql://localhost:3306/test?user=root
--------------------------------------------------------------------------------
/non-reactive/src/test/java/com/example/car/CachingTest.java:
--------------------------------------------------------------------------------
1 | package com.example.car;
2 |
3 | import com.example.car.domain.Car;
4 | import com.example.car.domain.CarRepository;
5 | import com.example.car.service.CarService;
6 | import org.junit.Test;
7 | import org.junit.runner.RunWith;
8 |
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
11 | import org.springframework.boot.test.context.SpringBootTest;
12 | import org.springframework.boot.test.mock.mockito.MockBean;
13 | import org.springframework.test.context.junit4.SpringRunner;
14 |
15 | import static org.mockito.ArgumentMatchers.anyString;
16 | import static org.mockito.BDDMockito.given;
17 | import static org.mockito.Mockito.times;
18 | import static org.mockito.Mockito.verify;
19 |
20 | @RunWith(SpringRunner.class)
21 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
22 | @AutoConfigureTestDatabase
23 | public class CachingTest {
24 |
25 | @Autowired
26 | private CarService service;
27 |
28 | @MockBean
29 | private CarRepository repository;
30 |
31 | @Test
32 | public void getCar_ReturnsCachedValue() throws Exception {
33 | given(repository.findByName(anyString())).willReturn(new Car("prius", "hybrid"));
34 | service.getCarDetails("prius");
35 | service.getCarDetails("prius");
36 | verify(repository, times(1)).findByName("prius");
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/non-reactive/src/test/java/com/example/car/IntegrationTests.java:
--------------------------------------------------------------------------------
1 | package com.example.car;
2 |
3 | import com.example.car.domain.Car;
4 | import org.junit.Test;
5 | import org.junit.runner.RunWith;
6 |
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.boot.test.context.SpringBootTest;
9 | import org.springframework.boot.test.web.client.TestRestTemplate;
10 | import org.springframework.http.HttpStatus;
11 | import org.springframework.http.ResponseEntity;
12 | import org.springframework.test.context.junit4.SpringRunner;
13 |
14 | import static org.assertj.core.api.Assertions.assertThat;
15 |
16 | @RunWith(SpringRunner.class)
17 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
18 | public class IntegrationTests {
19 |
20 | @Autowired
21 | private TestRestTemplate testRestTemplate;
22 |
23 | @Test
24 | public void getCar_WithName_ReturnsCar() {
25 | ResponseEntity responseEntity = this.testRestTemplate.getForEntity("/cars/{name}", Car.class, "prius");
26 | Car car = responseEntity.getBody();
27 | assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
28 | assertThat(car.getName()).isEqualTo("prius");
29 | assertThat(car.getType()).isEqualTo("hybrid");
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/non-reactive/src/test/java/com/example/car/domain/CarRepositoryTests.java:
--------------------------------------------------------------------------------
1 | package com.example.car.domain;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 |
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
8 | import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
9 | import org.springframework.test.context.junit4.SpringRunner;
10 |
11 | import static org.assertj.core.api.Assertions.assertThat;
12 |
13 | @RunWith(SpringRunner.class)
14 | @DataJpaTest
15 | public class CarRepositoryTests {
16 |
17 | @Autowired
18 | private CarRepository repository;
19 |
20 | @Autowired
21 | private TestEntityManager testEntityManager;
22 |
23 | @Test
24 | public void findByName_ReturnsCar() throws Exception {
25 | Car savedCar = testEntityManager.persistFlushFind(new Car("prius", "hybrid"));
26 | Car car = this.repository.findByName("prius");
27 | assertThat(car.getName()).isEqualTo(savedCar.getName());
28 | assertThat(car.getType()).isEqualTo(savedCar.getType());
29 | }
30 | }
--------------------------------------------------------------------------------
/non-reactive/src/test/java/com/example/car/service/CarServiceTest.java:
--------------------------------------------------------------------------------
1 | package com.example.car.service;
2 |
3 | import com.example.car.domain.Car;
4 | import com.example.car.domain.CarRepository;
5 | import com.example.car.web.CarNotFoundException;
6 | import org.junit.Before;
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 | import org.mockito.Mock;
10 | import org.mockito.junit.MockitoJUnitRunner;
11 |
12 | import static org.assertj.core.api.Assertions.assertThat;
13 | import static org.mockito.BDDMockito.given;
14 |
15 | @RunWith(MockitoJUnitRunner.class)
16 | public class CarServiceTest {
17 |
18 | @Mock
19 | private CarRepository carRepository;
20 |
21 | private CarService carService;
22 |
23 | @Before
24 | public void setUp() throws Exception {
25 | carService = new CarService(carRepository);
26 | }
27 |
28 | @Test
29 | public void getCarDetails_returnsCarInfo() {
30 | given(carRepository.findByName("prius")).willReturn(new Car("prius", "hybrid"));
31 |
32 | Car car = carService.getCarDetails("prius");
33 |
34 | assertThat(car.getName()).isEqualTo("prius");
35 | assertThat(car.getType()).isEqualTo("hybrid");
36 | }
37 |
38 | @Test(expected = CarNotFoundException.class)
39 | public void getCarDetails_whenCarNotFound() throws Exception {
40 | given(carRepository.findByName("prius")).willReturn(null);
41 |
42 | carService.getCarDetails("prius");
43 | }
44 | }
--------------------------------------------------------------------------------
/non-reactive/src/test/java/com/example/car/web/CarsControllerTests.java:
--------------------------------------------------------------------------------
1 | package com.example.car.web;
2 |
3 | import com.example.car.domain.Car;
4 | import com.example.car.service.CarService;
5 | import org.junit.Test;
6 | import org.junit.runner.RunWith;
7 |
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
10 | import org.springframework.boot.test.mock.mockito.MockBean;
11 | import org.springframework.test.context.junit4.SpringRunner;
12 | import org.springframework.test.web.servlet.MockMvc;
13 |
14 | import static org.mockito.ArgumentMatchers.any;
15 | import static org.mockito.Mockito.when;
16 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
17 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
18 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
19 |
20 | @RunWith(SpringRunner.class)
21 | @WebMvcTest
22 | public class CarsControllerTests {
23 |
24 | @Autowired
25 | private MockMvc mockMvc;
26 |
27 | @MockBean
28 | private CarService carService;
29 |
30 | @Test
31 | public void getCar_WithName_ReturnsCar() throws Exception {
32 | when(this.carService.getCarDetails("prius")).thenReturn(new Car("prius", "hybrid"));
33 | this.mockMvc.perform(get("/cars/{name}", "prius"))
34 | .andExpect(status().isOk())
35 | .andExpect(jsonPath("name").value("prius"))
36 | .andExpect(jsonPath("type").value("hybrid"));
37 | }
38 |
39 | @Test
40 | public void getCar_NotFound_Returns404() throws Exception {
41 | when(this.carService.getCarDetails(any())).thenReturn(null);
42 | this.mockMvc.perform(get("/cars/{name}", "prius"))
43 | .andExpect(status().isNotFound());
44 | }
45 |
46 | }
--------------------------------------------------------------------------------
/reactive/main/java/com/example/car/CarsApplication.java:
--------------------------------------------------------------------------------
1 | package com.example.car;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class CarsApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(CarsApplication.class, args);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/reactive/main/java/com/example/car/domain/Car.java:
--------------------------------------------------------------------------------
1 | package com.example.car.domain;
2 |
3 | import org.springframework.data.annotation.Id;
4 | import org.springframework.data.mongodb.core.mapping.Document;
5 |
6 | @Document
7 | public class Car {
8 |
9 | @Id
10 | private String id;
11 |
12 | private String name;
13 |
14 | private String type;
15 |
16 | public Car() {
17 | }
18 |
19 | public Car(String name, String type) {
20 | this.name = name;
21 | this.type = type;
22 | }
23 |
24 | public String getName() {
25 | return this.name;
26 | }
27 |
28 | public void setName(String name) {
29 | this.name = name;
30 | }
31 |
32 | public String getType() {
33 | return this.type;
34 | }
35 |
36 | public void setType(String type) {
37 | this.type = type;
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/reactive/main/java/com/example/car/domain/CarRepository.java:
--------------------------------------------------------------------------------
1 | package com.example.car.domain;
2 |
3 | import reactor.core.publisher.Mono;
4 |
5 | import org.springframework.data.repository.reactive.ReactiveCrudRepository;
6 |
7 | public interface CarRepository extends ReactiveCrudRepository {
8 |
9 | Mono findByName(String name);
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/reactive/main/java/com/example/car/web/CarController.java:
--------------------------------------------------------------------------------
1 | package com.example.car.web;
2 |
3 | import com.example.car.domain.Car;
4 | import com.example.car.domain.CarRepository;
5 | import reactor.core.publisher.Mono;
6 |
7 | import org.springframework.web.bind.annotation.GetMapping;
8 | import org.springframework.web.bind.annotation.PathVariable;
9 | import org.springframework.web.bind.annotation.RestController;
10 |
11 | @RestController
12 | public class CarController {
13 |
14 | private final CarRepository carRepository;
15 |
16 | public CarController(CarRepository carRepository) {
17 | this.carRepository = carRepository;
18 | }
19 |
20 | @GetMapping("/cars/{name}")
21 | public Mono getCar (@PathVariable String name) {
22 | return this.carRepository.findByName(name);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/reactive/main/resources/application.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mbhave/tdd-with-spring-boot/dabcbd2d5eb547a36c84011663cfd6c48b089602/reactive/main/resources/application.properties
--------------------------------------------------------------------------------
/reactive/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.example
7 | reactive-tdd-demo
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | reactive-tdd-demo
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.0.0.BUILD-SNAPSHOT
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 1.8
25 |
26 |
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-starter-data-mongodb-reactive
31 |
32 |
33 | org.springframework.boot
34 | spring-boot-starter-webflux
35 |
36 |
37 | de.flapdoodle.embed
38 | de.flapdoodle.embed.mongo
39 |
40 |
41 | org.springframework.boot
42 | spring-boot-starter-test
43 | test
44 |
45 |
46 | io.projectreactor
47 | reactor-test
48 | test
49 |
50 |
51 |
52 |
53 |
54 |
55 | org.springframework.boot
56 | spring-boot-maven-plugin
57 |
58 |
59 |
60 |
61 |
62 |
63 | spring-snapshots
64 | Spring Snapshots
65 | https://repo.spring.io/snapshot
66 |
67 | true
68 |
69 |
70 |
71 | spring-milestones
72 | Spring Milestones
73 | https://repo.spring.io/milestone
74 |
75 | false
76 |
77 |
78 |
79 |
80 |
81 |
82 | spring-snapshots
83 | Spring Snapshots
84 | https://repo.spring.io/snapshot
85 |
86 | true
87 |
88 |
89 |
90 | spring-milestones
91 | Spring Milestones
92 | https://repo.spring.io/milestone
93 |
94 | false
95 |
96 |
97 |
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/reactive/test/java/com/example/car/IntegrationTests.java:
--------------------------------------------------------------------------------
1 | package com.example.car;
2 |
3 | import com.example.car.domain.Car;
4 | import com.example.car.domain.CarRepository;
5 | import org.junit.Before;
6 | import org.junit.Test;
7 | import org.junit.runner.RunWith;
8 |
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.boot.test.context.SpringBootTest;
11 | import org.springframework.data.mongodb.core.CollectionOptions;
12 | import org.springframework.data.mongodb.core.ReactiveMongoOperations;
13 | import org.springframework.test.context.junit4.SpringRunner;
14 | import org.springframework.test.web.reactive.server.WebTestClient;
15 |
16 | import static org.assertj.core.api.Assertions.assertThat;
17 |
18 | @RunWith(SpringRunner.class)
19 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
20 | public class IntegrationTests {
21 |
22 | @Autowired
23 | private WebTestClient webTestClient;
24 |
25 | @Autowired
26 | private CarRepository carRepository;
27 |
28 | @Autowired
29 | private ReactiveMongoOperations operations;
30 |
31 | @Before
32 | public void setUp() throws Exception {
33 | this.operations
34 | .createCollection(Car.class, CollectionOptions.empty().size(1024 * 1024).maxDocuments( 100).capped())
35 | .then()
36 | .block();
37 |
38 | this.carRepository
39 | .save(new Car("prius", "hybrid"))
40 | .then()
41 | .block();
42 | }
43 |
44 | @Test
45 | public void getCar_WithName_ReturnsCar() {
46 | Car car = this.webTestClient.get().uri("/cars/{name}", "prius")
47 | .exchange().expectStatus().isOk()
48 | .expectBody(Car.class).returnResult().getResponseBody();
49 | assertThat(car.getName()).isEqualTo("prius");
50 | assertThat(car.getType()).isEqualTo("hybrid");
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/reactive/test/java/com/example/car/domain/CarRepositoryTests.java:
--------------------------------------------------------------------------------
1 | package com.example.car.domain;
2 |
3 | import org.junit.After;
4 | import org.junit.Before;
5 | import org.junit.Test;
6 | import org.junit.runner.RunWith;
7 | import reactor.test.StepVerifier;
8 |
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
11 | import org.springframework.test.context.junit4.SpringRunner;
12 |
13 | import static org.assertj.core.api.Assertions.assertThat;
14 |
15 | @RunWith(SpringRunner.class)
16 | @DataMongoTest
17 | public class CarRepositoryTests {
18 |
19 | @Autowired
20 | private CarRepository carRepository;
21 |
22 | @Before
23 | public void setUp() throws Exception {
24 | this.carRepository.save(new Car("prius", "hybrid"))
25 | .then()
26 | .block();
27 | }
28 |
29 | @After
30 | public void tearDown() throws Exception {
31 | carRepository.deleteAll()
32 | .then()
33 | .block();
34 | }
35 |
36 | @Test
37 | public void findByName_returnsCar() {
38 | StepVerifier.create(carRepository.findByName("prius"))
39 | .consumeNextWith(car -> {
40 | assertThat(car.getName()).isEqualTo("prius");
41 | assertThat(car.getType()).isEqualTo("hybrid");
42 | })
43 | .verifyComplete();
44 | }
45 |
46 | }
--------------------------------------------------------------------------------
/reactive/test/java/com/example/car/web/CarControllerTests.java:
--------------------------------------------------------------------------------
1 | package com.example.car.web;
2 |
3 | import com.example.car.domain.Car;
4 | import com.example.car.domain.CarRepository;
5 | import org.junit.Test;
6 | import org.junit.runner.RunWith;
7 | import reactor.core.publisher.Mono;
8 |
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
11 | import org.springframework.boot.test.mock.mockito.MockBean;
12 | import org.springframework.test.context.junit4.SpringRunner;
13 | import org.springframework.test.web.reactive.server.WebTestClient;
14 |
15 | import static org.mockito.BDDMockito.given;
16 |
17 | @RunWith(SpringRunner.class)
18 | @WebFluxTest
19 | public class CarControllerTests {
20 |
21 | @MockBean
22 | private CarRepository carRepository;
23 |
24 | @Autowired
25 | private WebTestClient webTestClient;
26 |
27 | @Test
28 | public void getCar_WithName_returnsCar() throws Exception {
29 | Car car = new Car("prius", "hybrid");
30 | given(carRepository.findByName("prius")).willReturn(Mono.just(car));
31 |
32 | this.webTestClient.get().uri("/cars/{name}", "prius")
33 | .exchange().expectStatus().isOk()
34 | .expectBody()
35 | .jsonPath("name").isEqualTo("prius")
36 | .jsonPath("type").isEqualTo("hybrid");
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------