WebTestClient 未注入
WebTestClient not injected
首先,我是 java 堆栈的新手,为了辩护,我可能会问一些愚蠢的问题,谢谢您的耐心等待!
我需要的:
集成测试但没有发出外部请求。这意味着我必须在堆栈中比普通单元测试更深的地方模拟依赖项。
我也不想在上下文中加载所有堆栈。
预期:
只能使用@BeanMock 模拟客户端并通过测试。 (根据我的试验,这只深入模拟了第一级)。
实际:
使用当前设置我得到
Error creating bean with name 'com.example.demo.SomeControllerTest': Unsatisfied dependency expressed through field 'webClient'
如果我使用 @WebFluxTest(SomeController.class)
和 ContextConfiguration(...)
,则客户端最终为空。如果我然后添加 @TestConfiguration
webflux 抱怨有一些注释冲突 @Configuration
例如。
非常感谢任何想法!
@RestController
public class SomeController {
private final SomeService someService;
@Autowired
public SomeController(SomeService someService) {
this.someService = someService;
}
@GetMapping(value = "/endpoint")
public Mono<String> endpoint() {
return someService.get();
}
}
@Service
public class SomeService {
private final Client client;
@Autowired
public SomeService(Client client) {
this.client = client;
}
public Mono<String> get() {
return client.build().get().retrieve().bodyToMono(String.class);
}
}
@Component
public class Client {
private final HttpServletRequest request;
@Autowired
public Client(HttpServletRequest request) {
this.request = request;
}
public WebClient build() {
return WebClient.builder()
.baseUrl("https://httpstat.us/200")
.build();
}
}
@RunWith(SpringRunner.class)
@TestConfiguration
@SpringBootTest(classes = {
SomeController.class,
SomeService.class
})
@AutoConfigureWebTestClient
public class SomeControllerTest {
@Autowired
private WebTestClient webClient;
@MockBean
private Client client;
@Before
public void setUp() {
when(client.build())
.thenReturn(WebClient.create("https://httpstat.us/201"));
}
@Test
public void deepMocking() {
webClient.get()
.uri("/endpoint")
.exchange()
.expectStatus().isOk()
.expectBody(String.class).isEqualTo("201 Created");
}
}
该错误表明您在尝试自动装配
WebTestClient
bean inside SomeControllerTest
class 你不能只自动装配 WebTestClient 它必须更改为
WebTestClient testClient = WebTestClient
.bindToServer()
.baseUrl("http://localhost:8080")
.build();
您可以从本文中找到有关 WebClient 的更多信息
http://www.baeldung.com/spring-5-webclient
@RunWith(SpringRunner.class)
@WebFluxTest(SomeController.class)
@ContextConfiguration(classes = {
SomeController.class,
SomeService.class
})
public class SomeControllerTest {
@Autowired
private WebTestClient webClient;
// ...
}
这是必需的组合,但我不明白为什么需要将 SomeController.class
添加到活动上下文中,@WebFluxTest
不也这样做吗?
或
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {
SomeController.class,
SomeService.class,
})
// @AutoConfigureWebTestClient // does absolutely nothing?
public class SomeControllerTest {
@Autowired
private SomeController controller;
// ...
@Test
public void deepMocking() {
WebTestClient.bindToController(controller)
.build()
.get()
.uri("/endpoint")
.exchange()
.expectStatus().isOk()
.expectBody(String.class).isEqualTo("201 Created");
}
}
经过 03 天的挣扎,我就是这样解决的:
感谢 llooottt : https://www.baeldung.com/spring-5-webclient
@WebFluxTest
public class AnimeControllerIntegrTest{
WebTestClient testClient;
@Test
public void get_RA() {
testClient = WebTestClient.bindToServer().baseUrl("http://localhost:8080/animes").build();
RestAssuredWebTestClient
.given()
.webTestClient(testClient)
.when()
.get()
.then()
.statusCode(OK.value())
.body("name" ,hasItem("paulo"))
;
}
}
首先,我是 java 堆栈的新手,为了辩护,我可能会问一些愚蠢的问题,谢谢您的耐心等待!
我需要的:
集成测试但没有发出外部请求。这意味着我必须在堆栈中比普通单元测试更深的地方模拟依赖项。 我也不想在上下文中加载所有堆栈。
预期:
只能使用@BeanMock 模拟客户端并通过测试。 (根据我的试验,这只深入模拟了第一级)。
实际:
使用当前设置我得到
Error creating bean with name 'com.example.demo.SomeControllerTest': Unsatisfied dependency expressed through field 'webClient'
如果我使用 @WebFluxTest(SomeController.class)
和 ContextConfiguration(...)
,则客户端最终为空。如果我然后添加 @TestConfiguration
webflux 抱怨有一些注释冲突 @Configuration
例如。
非常感谢任何想法!
@RestController
public class SomeController {
private final SomeService someService;
@Autowired
public SomeController(SomeService someService) {
this.someService = someService;
}
@GetMapping(value = "/endpoint")
public Mono<String> endpoint() {
return someService.get();
}
}
@Service
public class SomeService {
private final Client client;
@Autowired
public SomeService(Client client) {
this.client = client;
}
public Mono<String> get() {
return client.build().get().retrieve().bodyToMono(String.class);
}
}
@Component
public class Client {
private final HttpServletRequest request;
@Autowired
public Client(HttpServletRequest request) {
this.request = request;
}
public WebClient build() {
return WebClient.builder()
.baseUrl("https://httpstat.us/200")
.build();
}
}
@RunWith(SpringRunner.class)
@TestConfiguration
@SpringBootTest(classes = {
SomeController.class,
SomeService.class
})
@AutoConfigureWebTestClient
public class SomeControllerTest {
@Autowired
private WebTestClient webClient;
@MockBean
private Client client;
@Before
public void setUp() {
when(client.build())
.thenReturn(WebClient.create("https://httpstat.us/201"));
}
@Test
public void deepMocking() {
webClient.get()
.uri("/endpoint")
.exchange()
.expectStatus().isOk()
.expectBody(String.class).isEqualTo("201 Created");
}
}
该错误表明您在尝试自动装配
WebTestClient
bean inside SomeControllerTest
class 你不能只自动装配 WebTestClient 它必须更改为
WebTestClient testClient = WebTestClient
.bindToServer()
.baseUrl("http://localhost:8080")
.build();
您可以从本文中找到有关 WebClient 的更多信息 http://www.baeldung.com/spring-5-webclient
@RunWith(SpringRunner.class)
@WebFluxTest(SomeController.class)
@ContextConfiguration(classes = {
SomeController.class,
SomeService.class
})
public class SomeControllerTest {
@Autowired
private WebTestClient webClient;
// ...
}
这是必需的组合,但我不明白为什么需要将 SomeController.class
添加到活动上下文中,@WebFluxTest
不也这样做吗?
或
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {
SomeController.class,
SomeService.class,
})
// @AutoConfigureWebTestClient // does absolutely nothing?
public class SomeControllerTest {
@Autowired
private SomeController controller;
// ...
@Test
public void deepMocking() {
WebTestClient.bindToController(controller)
.build()
.get()
.uri("/endpoint")
.exchange()
.expectStatus().isOk()
.expectBody(String.class).isEqualTo("201 Created");
}
}
经过 03 天的挣扎,我就是这样解决的:
感谢 llooottt : https://www.baeldung.com/spring-5-webclient
@WebFluxTest
public class AnimeControllerIntegrTest{
WebTestClient testClient;
@Test
public void get_RA() {
testClient = WebTestClient.bindToServer().baseUrl("http://localhost:8080/animes").build();
RestAssuredWebTestClient
.given()
.webTestClient(testClient)
.when()
.get()
.then()
.statusCode(OK.value())
.body("name" ,hasItem("paulo"))
;
}
}