我有一个接收不同类型消息的Camel路由,我只能控制某些消息。我想检查某些消息是否至少收到一次,并忽略流经该路由的任何其他类型的消息。这意味着我不知道模拟端点在断言之前需要接收多少消息。
下面的代码演示了这个问题。 testExactBodies()测试工作正常,但我不知道如何使testLenientBodies()工作。
这是一个简化的示例,在现实世界中,消息体是复杂的XML,我需要对它们做出的断言更复杂。
import org.apache.camel.LoggingLevel;
import org.apache.camel.RoutesBuilder;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.junit.Test;
public class ExpectationTest extends CamelTestSupport {
private static final String MOCK_ENDPOINT = "mock:expectation_mock";
private static final String START_URI = "direct:expectation_test";
@Override
protected RoutesBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
from(START_URI).routeId("expectation_test")
.log(LoggingLevel.INFO, "$simple{body}")
.to(MOCK_ENDPOINT);
}
};
}
@Test
public void testExactBodies() throws InterruptedException {
// Get the mock endpoint
MockEndpoint mockEndpoint = getMockEndpoint(MOCK_ENDPOINT);
// Set the expectations that we want to check.
// Here we expect exactly these 3 bodies
// This will implicitly call mockEndpoint.setExpectedMessageCount(3)
mockEndpoint.expectedBodiesReceived("x", "y", "z");
// Sets the timeout to wait for the expectations to be satisfied
mockEndpoint.setResultWaitTime(10000);
// Send the testdata to the route
template.sendBody(START_URI, "x");
template.sendBody(START_URI, "y");
template.sendBody(START_URI, "z");
// Assert that the expectations are satisfied. Will wait until expectations are satisfied or a timeout occurs
mockEndpoint.assertIsSatisfied();
}
@Test
public void testLenientBodies() throws InterruptedException {
// Get the mock endpoint
MockEndpoint mockEndpoint = getMockEndpoint(MOCK_ENDPOINT);
// Set the expectations that we want to check.
// We want to check that the bodies "x", "y" and "z" arrive at least once and in any order and ignore any other bodies, but how?
mockEndpoint.expectedBodiesReceivedInAnyOrder("x", "y", "z");
// mockEndpoint.expectedBodiesReceivedInAnyOrderAndIgnoreOtherBodies("x", "y", "z");
// Sets the timeout to wait for the expectations to be satisfied
mockEndpoint.setResultWaitTime(10000);
// Send the testdata to the route
template.sendBody(START_URI, "a");
template.sendBody(START_URI, "y");
template.sendBody(START_URI, "z");
template.sendBody(START_URI, "b");
template.sendBody(START_URI, "y");
template.sendBody(START_URI, "r");
template.sendBody(START_URI, "c");
template.sendBody(START_URI, "x");
// Assert that the expectations are satisfied. Will wait until expectations are satisfied or a timeout occurs
mockEndpoint.assertIsSatisfied();
}
}
编辑==============================
解决方法是:
@Test
public void testLenientBodiesBruteForce() throws InterruptedException {
// Get the mock endpoint
MockEndpoint mockEndpoint = getMockEndpoint(MOCK_ENDPOINT);
// Send the testdata to the route
template.sendBody(START_URI, "a");
template.sendBody(START_URI, "y");
template.sendBody(START_URI, "z"); // Comment out this line to make the test fail
template.sendBody(START_URI, "b");
template.sendBody(START_URI, "y");
template.sendBody(START_URI, "r");
template.sendBody(START_URI, "c");
template.sendBody(START_URI, "x");
// We want to check that the bodies "x", "y" and "z" arrive at least once and in any order and ignore any other bodies
boolean satisfied = false;
int timeout = 10;
int i = 0;
while (!satisfied && i < timeout) {
Set<String> expectedBodies = new HashSet<>();
expectedBodies.add("x");
expectedBodies.add("y");
expectedBodies.add("z");
for (Exchange exchange : mockEndpoint.getExchanges()) {
expectedBodies.remove(exchange.getIn().getBody(String.class));
}
System.out.println("ExpectedBodies not yet seen: " + expectedBodies);
satisfied = expectedBodies.isEmpty();
if (!satisfied) {
Thread.sleep(1000);
i++;
}
}
assertTrue(satisfied);
}