Spring 集成组件的 Junit
Junit for Spring Integration Components
我有以下调用 REST 服务的配置设置。
@Bean
public MessageChannel requestChannel() {
SubscribableChannel requestChannel= new DirectChannel();
return requestChannel;
}
@Bean
public MessageChannel responseChannel() {
SubscribableChannel responseChannel = new DirectChannel();
return responseChannel;
}
@Bean
@ServiceActivator(inputChannel = "requestChannel")
public MessageHandler httResponseMessageHandler(MessageChannel responseChannel,
HeaderMapper<HttpHeaders> headerMapper, RequestHandlerRetryAdvice retryAdvice) {
List<Advice> list = new ArrayList<>();
list.add(retryAdvice);
HttpRequestExecutingMessageHandler handler = new HttpRequestExecutingMessageHandler("https://localhost:8080/myrest/service/");
handler.setHttpMethod(HttpMethod.POST);
handler.setHeaderMapper(headerMapper);
handler.setOutputChannel(responseChannel);
handler.setExpectedResponseType(RtpResponse.class);
handler.setAdviceChain(list);
return handler;
}
下面是网关和服务激活器发送请求和获取响应的配置。
@Override
@ServiceActivator(inputChannel="responseChannel")
public void receiveResponse(Message<RtpResponse> message) {
LOGGER.info("Message: " + message);
LOGGER.info("Message: " + message.getPayload());
LOGGER.info(message.getClass().getCanonicalName());
}
@Override
@Gateway(requestChannel = "requestChannel")
public void sendRequest(RtpRequestBody requestBody) {
requestChannel
.send(
MessageBuilder.withPayload(requestBody)
.setHeader("Accept","application/json")
.setHeader(MessageHeaders.CONTENT_TYPE,"application/json")
.setHeader(MessageHeaders.ERROR_CHANNEL,errorChannel)
.build()
);
}
我一直纠结于如何为这个流程编写 Junit。我不确定我是否需要将此流程重组为 IntegrationFlow,这将有助于为此编写 Junit 测试。需要的建议。
不确定你有什么问题,但你只需要为那个 sendRequest()
获取一个网关 bean 并调用它:
@Autowired
MyGateway myGateway;
@Test
void myTest() {
this.myGateway.sendRequest(...);
}
不确定您为什么不期望从该网关方法获得 return,但这就是您的逻辑。要处理 responseChannel
中的回复,您可以考虑使用 Spring 集成测试框架及其 MockIntegration.mockMessageHandler()
和 MockIntegrationContext.substituteMessageHandlerFor()
将您的 receiveResponse()
服务激活器替换为您可以在测试用例中验证和断言的内容。
在参考手册中查看更多信息:https://docs.spring.io/spring-integration/docs/5.0.5.RELEASE/reference/html/testing.html#test-context
更新
Unfortunately, we cannot upgrade to version 5.0.5. Could you please guide me to spring integration testing documentation for version 4.3.9
不,没有这样的。这确实是 Spring Integration 5.0 中的一项新功能:https://docs.spring.io/spring-integration/docs/5.0.5.RELEASE/reference/html/whats-new.html。
您可以在执行测试用例之前获取 requestChannel
bean 并调用其 addInterceptor(ChannelInterceptor interceptor)
。在 ChannelInterceptor.perSend()
中你可以得到一条回复消息并验证它。
在 Artem 的回答的帮助下
@Autowired
private SubscribableChannel employeeGetMethodResponseChannel;
@Autowired
private EmployeeSearchService employeeSearchService;
@Mock
private RestTemplate restTemplateMock;
private EmployeeDetail employeeDetailInResponse;
private Employee employeeInRequest;
@Before
public void setUp() {
employeeInRequest = new Employee();
employeeInRequest.setEmployeeId(1L);
employeeDetailInResponse = new EmployeeDetail();
employeeDetailInResponse.setEmployeeId(1L);
}
@Test
public void testGetRequest() {
Mockito.when(restTemplateMock.postForObject("https://localhost:8080/myrest/service/", EmployeeDetail.class))
.thenReturn(employeeDetailInResponse);
this.employeeSearchService.employeeSearch(employeeInRequest);
}
@Test
public void testResponse() {
this.responseChannel.subscribe(new MessageHandler() {
@Override
public void handleMessage(Message<?> message) throws MessagingException {
Assert.assertTrue("Test failed", ((EmployeeDetail) message.getPayload()).getEmployeeId().equals(1L));
}
});
}
我有以下调用 REST 服务的配置设置。
@Bean
public MessageChannel requestChannel() {
SubscribableChannel requestChannel= new DirectChannel();
return requestChannel;
}
@Bean
public MessageChannel responseChannel() {
SubscribableChannel responseChannel = new DirectChannel();
return responseChannel;
}
@Bean
@ServiceActivator(inputChannel = "requestChannel")
public MessageHandler httResponseMessageHandler(MessageChannel responseChannel,
HeaderMapper<HttpHeaders> headerMapper, RequestHandlerRetryAdvice retryAdvice) {
List<Advice> list = new ArrayList<>();
list.add(retryAdvice);
HttpRequestExecutingMessageHandler handler = new HttpRequestExecutingMessageHandler("https://localhost:8080/myrest/service/");
handler.setHttpMethod(HttpMethod.POST);
handler.setHeaderMapper(headerMapper);
handler.setOutputChannel(responseChannel);
handler.setExpectedResponseType(RtpResponse.class);
handler.setAdviceChain(list);
return handler;
}
下面是网关和服务激活器发送请求和获取响应的配置。
@Override
@ServiceActivator(inputChannel="responseChannel")
public void receiveResponse(Message<RtpResponse> message) {
LOGGER.info("Message: " + message);
LOGGER.info("Message: " + message.getPayload());
LOGGER.info(message.getClass().getCanonicalName());
}
@Override
@Gateway(requestChannel = "requestChannel")
public void sendRequest(RtpRequestBody requestBody) {
requestChannel
.send(
MessageBuilder.withPayload(requestBody)
.setHeader("Accept","application/json")
.setHeader(MessageHeaders.CONTENT_TYPE,"application/json")
.setHeader(MessageHeaders.ERROR_CHANNEL,errorChannel)
.build()
);
}
我一直纠结于如何为这个流程编写 Junit。我不确定我是否需要将此流程重组为 IntegrationFlow,这将有助于为此编写 Junit 测试。需要的建议。
不确定你有什么问题,但你只需要为那个 sendRequest()
获取一个网关 bean 并调用它:
@Autowired
MyGateway myGateway;
@Test
void myTest() {
this.myGateway.sendRequest(...);
}
不确定您为什么不期望从该网关方法获得 return,但这就是您的逻辑。要处理 responseChannel
中的回复,您可以考虑使用 Spring 集成测试框架及其 MockIntegration.mockMessageHandler()
和 MockIntegrationContext.substituteMessageHandlerFor()
将您的 receiveResponse()
服务激活器替换为您可以在测试用例中验证和断言的内容。
在参考手册中查看更多信息:https://docs.spring.io/spring-integration/docs/5.0.5.RELEASE/reference/html/testing.html#test-context
更新
Unfortunately, we cannot upgrade to version 5.0.5. Could you please guide me to spring integration testing documentation for version 4.3.9
不,没有这样的。这确实是 Spring Integration 5.0 中的一项新功能:https://docs.spring.io/spring-integration/docs/5.0.5.RELEASE/reference/html/whats-new.html。
您可以在执行测试用例之前获取 requestChannel
bean 并调用其 addInterceptor(ChannelInterceptor interceptor)
。在 ChannelInterceptor.perSend()
中你可以得到一条回复消息并验证它。
在 Artem 的回答的帮助下
@Autowired
private SubscribableChannel employeeGetMethodResponseChannel;
@Autowired
private EmployeeSearchService employeeSearchService;
@Mock
private RestTemplate restTemplateMock;
private EmployeeDetail employeeDetailInResponse;
private Employee employeeInRequest;
@Before
public void setUp() {
employeeInRequest = new Employee();
employeeInRequest.setEmployeeId(1L);
employeeDetailInResponse = new EmployeeDetail();
employeeDetailInResponse.setEmployeeId(1L);
}
@Test
public void testGetRequest() {
Mockito.when(restTemplateMock.postForObject("https://localhost:8080/myrest/service/", EmployeeDetail.class))
.thenReturn(employeeDetailInResponse);
this.employeeSearchService.employeeSearch(employeeInRequest);
}
@Test
public void testResponse() {
this.responseChannel.subscribe(new MessageHandler() {
@Override
public void handleMessage(Message<?> message) throws MessagingException {
Assert.assertTrue("Test failed", ((EmployeeDetail) message.getPayload()).getEmployeeId().equals(1L));
}
});
}