11.3 测试响应式接口
11.3 测试响应式Controller
在测试响应式
11.3.1 测试GET 请求
对于/design/recent
路径发出了
程序清单
package tacos;
import static org.mockito.Mockito.*;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.http.MediaType;
import org.springframework.test.web.reactive.server.WebTestClient;
import reactor.core.publisher.Flux;
import tacos.Ingredient.Type;
import tacos.data.TacoRepository;
import tacos.web.api.DesignTacoController;
public class DesignTacoControllerTest {
@Test
public void shouldReturnRecentTacos() {
Taco[] tacos = {
testTaco(1L), testTaco(2L), testTaco(3L), testTaco(4L),
testTaco(5L), testTaco(6L), testTaco(7L), testTaco(8L),
testTaco(9L), testTaco(10L), testTaco(11L), testTaco(12L),
testTaco(13L), testTaco(14L), testTaco(15L), testTaco(16L)
};
Flux<Taco> tacoFlux = Flux.just(tacos);
TacoRepository tacoRepo = Mockito.mock(TacoRepository.class);
when(tacoRepo.findAll()).thenReturn(tacoFlux);
WebTestClient testClient = WebTestClient.bindToController(
new DesignTacoController(tacoRepo)).build();
testClient.get().uri("/design/recent")
.exchange().expectStatus().isOk().expectBody()
.jsonPath("$").isArray()
.jsonPath("$").isNotEmpty()
.jsonPath("$[0].id").isEqualTo(tacos[0].getId().toString())
.jsonPath("$[0].name").isEqualTo("Taco 1")
.jsonPath("$[1].id").isEqualTo(tacos[1].getId().toString())
.jsonPath("$[1].name").isEqualTo("Taco 2")
.jsonPath("$[11].id").isEqualTo(tacos[11].getId().toString())
...
.jsonPath("$[11].name").isEqualTo("Taco 12")
.jsonPath("$[12]").doesNotExist()
.jsonPath("$[12]").doesNotExist();
}
...
}
对于将由
private Taco testTaco(Long number) {
Taco taco = new Taco();
taco.setId(UUID.randomUUID());
taco.setName("Taco " + number);
List<IngredientUDT> ingredients = new ArrayList<>();
ingredients.add(
new IngredientUDT("INGA", "Ingredient A", Type.WRAP));
ingredients.add(
new IngredientUDT("INGB", "Ingredient B", Type.PROTEIN));
taco.setIngredients(ingredients);
return taco;
}
为了简单起见,所有的测试
同时,在
完成所有设置后,现在可以使用/design/recent
提交
最后,可以确认响应与预期一致。通过调用
如果
例如,假设在一个名为/tacos
下的类路径中。然后重写
ClassPathResource recentsResource = new ClassPathResource("/tacos/recent-tacos.json");
String recentsJson = StreamUtils.copyToString(
recentsResource.getInputStream(), Charset.defaultCharset());
testClient.get().uri("/design/recent")
.accept(MediaType.APPLICATION_JSON)
.exchange().expectStatus().isOk().expectBody()
.json(recentsJson);
因为
testClient.get().uri("/design/recent")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk()
.expectBodyList(Taco.class)
.contains(Arrays.copyOf(tacos, 12));
在这里,断言响应体包含的列表,与在测试方法开始时创建的原始
11.3.2 测试POST 请求
表
GET | .get() |
POST | .post() |
PUT | .put() |
PATCH | .patch() |
DELETE | .delete() |
HEAD | .head() |
作为针对/design
提交
@Test
public void shouldSaveATaco() {
TacoRepository tacoRepo = Mockito.mock(TacoRepository.class);
Mono<Taco> unsavedTacoMono = Mono.just(testTaco(null));
Taco savedTaco = testTaco(null);
savedTaco.setId(1L);
Mono<Taco> savedTacoMono = Mono.just(savedTaco);
when(tacoRepo.save(any())).thenReturn(savedTacoMono);
WebTestClient testClient = WebTestClient.bindToController(
new DesignTacoController(tacoRepo)).build();
testClient.post()
.uri("/design")
.contentType(MediaType.APPLICATION_JSON)
.body(unsavedTacoMono, Taco.class)
.exchange()
.expectStatus().isCreated()
.expectBody(Taco.class)
.isEqualTo(savedTaco);
}
与前面的测试方法一样,/design
提交
11.3.3 使用线上服务器进行测试
到目前为止,编写的测试依赖于
要编写
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
public class DesignTacoControllerWebTest {
@Autowired
private WebTestClient testClient;
}
通过将
@Test
public void shouldReturnRecentTacos() throws IOException {
testClient.get().uri("/design/recent")
.accept(MediaType.APPLICATION_JSON).exchange()
.expectStatus().isOk()
.expectBody()
.jsonPath("$[?(@.id == 'TACO1')].name").isEqualTo("Carnivore")
.jsonPath("$[?(@.id == 'TACO2')].name").isEqualTo("Bovine Bounty")
.jsonPath("$[?(@.id == 'TACO3')].name").isEqualTo("Veg-Out");
}
毫无疑问,你已经注意到这个新版本的
在测试过程中,当需要使用