为什么存根 sftp Camel 端点不遵守此测试中的 "include" 选项?
Why isn't a stubbed sftp Camel endpoint respecting the "include" option in this test?
我正在尝试存根一个 sftp 消费者端点以用于测试目的 - 我还不想尝试启动一个容器。这是我到目前为止所得到的:
import org.apache.camel.*;
import org.apache.camel.builder.AdviceWith;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.model.RouteDefinition;
import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
import org.apache.camel.test.spring.junit5.MockEndpointsAndSkip;
import org.apache.camel.test.spring.junit5.UseAdviceWith;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.DirtiesContext;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.File;
import static com.routes.zipping.Resources.*;
/**
* Tests a from() route, the scheme of which is not "direct", but is "sftp".
*/
@CamelSpringBootTest
@SpringBootTest(properties = "camel.springboot.java-routes-include-pattern=**/GetWretchedBillImagesRoute*")
@MockEndpointsAndSkip("direct:split")
@UseAdviceWith
public class ITGetWretchedBIllImagesRoute {
@Produce
ProducerTemplate producerTemplate;
@Autowired
CamelContext camelContext;
@EndpointInject("mock:direct:split")
MockEndpoint mockConvert;
private String stubUrl;
@Test
@DisplayName("ZIPs are count")
@DirtiesContext
@Disabled("This gives back inconsistent results or seems to ignore the 'include' file option, so zip of any name or even a pdf is received at mocked endpoint.")
void testGetFile_ZipMessageCountsButNotPdf() throws Exception {
File zip = new File(TEST_PATH + ZIP + IN + "zipWith3Files.zip");
assertTrue(zip.exists(), "The required test resource file is unavailable");
File pdf = new File(TEST_PATH + PDF + IN + "myPdf.pdf");
assertTrue(pdf.exists(), "The required test resource file is unavailable");
AdviceWith.adviceWith(camelContext, "Wretched Bill Image ZIP Poller", routeBuilder -> {
RouteDefinition rd = routeBuilder.getOriginalRoute();
rd.setAutoStartup("true");
var originalUrl = rd.getEndpointUrl();
System.out.println("Advicing " + originalUrl);
stubUrl = "stub:" + originalUrl;
routeBuilder.replaceFromWith(stubUrl);
});
camelContext.start();
mockConvert.expectedMessageCount(0);
producerTemplate.sendBody(stubUrl, zip);
producerTemplate.sendBody(stubUrl, zip);
producerTemplate.sendBody(stubUrl, pdf);
producerTemplate.sendBody(stubUrl, pdf);
mockConvert.assertIsSatisfied();
}
}
这里是原路线:
import com.routes.client.props.WretchedRouteProps;
import org.apache.camel.builder.RouteBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class GetWretchedBillImagesRoute extends RouteBuilder {
public static String ROUTE_ID = "Wretched Bill Image ZIP Poller";
private final WretchedRouteProps arp;
@Autowired
public GetWretchedBillImagesRoute(WretchedRouteProps wretchedRouteProps) {
this.arp = wretchedRouteProps;
}
//@formatter:off
@Override
public void configure() throws Exception {
from(getSftpStartEndpoint())
.log("Polled for zipped image files for Wretched")
.id("Wretched Bill Image ZIP Poller")
.routeId("Wretched Bill Image ZIP Poller")
.setHeader("unzipTo", constant(arp.getFileDestination()))
.setHeader("nameMatters", constant(arp.nameMatters()))
.setHeader("client", constant("Wretched"))
.autoStartup(arp.isAutoStart() || arp.shouldAutoStartThisRoute())
.to("direct:split");
}
//@formatter:on
private String getSftpStartEndpoint() {
return new StringBuilder()
.append("sftp://").append(arp.getSftpUser()).append("@").append(arp.getSftpHost()).append("/")
.append(arp.getSftpPath())
.append("?password=").append(arp.getSftpPassword())
.append("&scheduler=spring&scheduler.cron=").append(arp.getRouteSchedule())
.append("&readLock=changed&readLockMinAge=300000")
.append("&streamDownload=true&stepwise=false")
.append("&timeUnit=MINUTES")
.append("&noop=").append(arp.shouldMoveFromFtp())
.append("&move=").append(arp.getArchiveDestination())
.append("&include=").append(arp.getWretchedBillZipRegex())
.toString();
}
}
我注意到这会在多重期望下通过:
mockConvert.expectedMessageCount(0);
mockConvert.expectedMessageCount(4);
只有当我期望的消息比我产生的消息多时,它才会失败,例如,
mockConvert.expectedMessageCount(5);
所以 1) 考虑到“包含”正则表达式中的不匹配,为什么存根选项不排除我通过制作者发送的 所有 文件,以及2)为什么多重期望通过?顺便说一句,如果有更好的方法在没有测试容器的情况下测试现有的 sftp 消费者端点,请告诉我或指点我。
我只知道你第二个问题的答案:
2
MockEndpoint.expectedMessageCount(i)
仅确保收到 i
条消息。一旦达到消息计数,它就会认为期望得到满足。不考虑任何无关的消息。快速浏览一下 documentation 说明您可以使用 setAssertPeriod(l)
强制执行预期的消息计数,即使在该时间段之后也是如此。 5 没有通过的原因是端点从未收到第五条消息。
我正在尝试存根一个 sftp 消费者端点以用于测试目的 - 我还不想尝试启动一个容器。这是我到目前为止所得到的:
import org.apache.camel.*;
import org.apache.camel.builder.AdviceWith;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.model.RouteDefinition;
import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
import org.apache.camel.test.spring.junit5.MockEndpointsAndSkip;
import org.apache.camel.test.spring.junit5.UseAdviceWith;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.DirtiesContext;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.File;
import static com.routes.zipping.Resources.*;
/**
* Tests a from() route, the scheme of which is not "direct", but is "sftp".
*/
@CamelSpringBootTest
@SpringBootTest(properties = "camel.springboot.java-routes-include-pattern=**/GetWretchedBillImagesRoute*")
@MockEndpointsAndSkip("direct:split")
@UseAdviceWith
public class ITGetWretchedBIllImagesRoute {
@Produce
ProducerTemplate producerTemplate;
@Autowired
CamelContext camelContext;
@EndpointInject("mock:direct:split")
MockEndpoint mockConvert;
private String stubUrl;
@Test
@DisplayName("ZIPs are count")
@DirtiesContext
@Disabled("This gives back inconsistent results or seems to ignore the 'include' file option, so zip of any name or even a pdf is received at mocked endpoint.")
void testGetFile_ZipMessageCountsButNotPdf() throws Exception {
File zip = new File(TEST_PATH + ZIP + IN + "zipWith3Files.zip");
assertTrue(zip.exists(), "The required test resource file is unavailable");
File pdf = new File(TEST_PATH + PDF + IN + "myPdf.pdf");
assertTrue(pdf.exists(), "The required test resource file is unavailable");
AdviceWith.adviceWith(camelContext, "Wretched Bill Image ZIP Poller", routeBuilder -> {
RouteDefinition rd = routeBuilder.getOriginalRoute();
rd.setAutoStartup("true");
var originalUrl = rd.getEndpointUrl();
System.out.println("Advicing " + originalUrl);
stubUrl = "stub:" + originalUrl;
routeBuilder.replaceFromWith(stubUrl);
});
camelContext.start();
mockConvert.expectedMessageCount(0);
producerTemplate.sendBody(stubUrl, zip);
producerTemplate.sendBody(stubUrl, zip);
producerTemplate.sendBody(stubUrl, pdf);
producerTemplate.sendBody(stubUrl, pdf);
mockConvert.assertIsSatisfied();
}
}
这里是原路线:
import com.routes.client.props.WretchedRouteProps;
import org.apache.camel.builder.RouteBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class GetWretchedBillImagesRoute extends RouteBuilder {
public static String ROUTE_ID = "Wretched Bill Image ZIP Poller";
private final WretchedRouteProps arp;
@Autowired
public GetWretchedBillImagesRoute(WretchedRouteProps wretchedRouteProps) {
this.arp = wretchedRouteProps;
}
//@formatter:off
@Override
public void configure() throws Exception {
from(getSftpStartEndpoint())
.log("Polled for zipped image files for Wretched")
.id("Wretched Bill Image ZIP Poller")
.routeId("Wretched Bill Image ZIP Poller")
.setHeader("unzipTo", constant(arp.getFileDestination()))
.setHeader("nameMatters", constant(arp.nameMatters()))
.setHeader("client", constant("Wretched"))
.autoStartup(arp.isAutoStart() || arp.shouldAutoStartThisRoute())
.to("direct:split");
}
//@formatter:on
private String getSftpStartEndpoint() {
return new StringBuilder()
.append("sftp://").append(arp.getSftpUser()).append("@").append(arp.getSftpHost()).append("/")
.append(arp.getSftpPath())
.append("?password=").append(arp.getSftpPassword())
.append("&scheduler=spring&scheduler.cron=").append(arp.getRouteSchedule())
.append("&readLock=changed&readLockMinAge=300000")
.append("&streamDownload=true&stepwise=false")
.append("&timeUnit=MINUTES")
.append("&noop=").append(arp.shouldMoveFromFtp())
.append("&move=").append(arp.getArchiveDestination())
.append("&include=").append(arp.getWretchedBillZipRegex())
.toString();
}
}
我注意到这会在多重期望下通过:
mockConvert.expectedMessageCount(0);
mockConvert.expectedMessageCount(4);
只有当我期望的消息比我产生的消息多时,它才会失败,例如,
mockConvert.expectedMessageCount(5);
所以 1) 考虑到“包含”正则表达式中的不匹配,为什么存根选项不排除我通过制作者发送的 所有 文件,以及2)为什么多重期望通过?顺便说一句,如果有更好的方法在没有测试容器的情况下测试现有的 sftp 消费者端点,请告诉我或指点我。
我只知道你第二个问题的答案:
2
MockEndpoint.expectedMessageCount(i)
仅确保收到 i
条消息。一旦达到消息计数,它就会认为期望得到满足。不考虑任何无关的消息。快速浏览一下 documentation 说明您可以使用 setAssertPeriod(l)
强制执行预期的消息计数,即使在该时间段之后也是如此。 5 没有通过的原因是端点从未收到第五条消息。