骆驼路由单元测试导致FailedToCreateRouteException

时间:2015-09-17 14:52:02

标签: java unit-testing apache-camel

我想对Camel路线进行单元测试。这是一个沙盒示例,说明了单元测试时得到的异常。如何通过异常以便我可以对SandboxRoute进行单元测试?

Sandbox.java:

package sandbox;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.Processor;
import org.apache.camel.spring.SpringCamelContext;
import org.apache.camel.spring.SpringRouteBuilder;
import org.apache.camel.spring.javaconfig.CamelConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import scala.collection.mutable.StringBuilder;

@ComponentScan
public class Sandbox {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(RouteConfiguration.class);
        SandboxWorker sandboxWorker = context.getBean("sandboxWorker", SandboxWorker.class);
        sandboxWorker.start();
        context.close();
    }
}

@Component
class SandboxWorker {

    @Autowired
    private SpringCamelContext camelContext;

    public void start() {
        Map<String, Object> headers = new HashMap<String, Object>();
        Object body = new Object();
        camelContext.createProducerTemplate().sendBodyAndHeaders("direct:ProcessTheRecords", body, headers);
    }

}

class SandboxRoute extends SpringRouteBuilder {
    @Override
    public void configure() {
        from("direct:ProcessTheRecords").processRef("getAllTheRecords").process(new Processor() {

            @Override
            public void process(Exchange exchange) throws Exception {
                Message in = exchange.getIn();
                StringBuilder body = in.getBody(StringBuilder.class);
                body.append("Sand");
                body.append('\n');
                in.setBody(body);
            }
        }).to("direct:RecordProcessor");
    }
}

class GetAllTheRecords implements Processor {

    @Autowired
    private SandboxService sandboxService;

    public void process(Exchange exchange) throws Exception {

        StringBuilder body = new StringBuilder();
        body.append(sandboxService.getSandLevel());
        body.append('\n');
        body.append(sandboxService.getSandLevel());
        body.append('\n');
        body.append(sandboxService.getSandLevel());
        body.append('\n');

        Message in = exchange.getIn();
        in.setBody(body);
    }
}

@Service
class SandboxService {

    Random rand;

    public SandboxService() {
        rand = new Random(new Date().getTime());
    }

    public String getSandLevel() {
        return Long.toString(rand.nextLong());
    }
}

class RecordProcessor extends SpringRouteBuilder {
    @Override
    public void configure() {
        from("direct:RecordProcessor").to("log:out");
    }
}

@Configuration
class RouteConfiguration extends CamelConfiguration {

    @Autowired
    private ApplicationContext applicationContext;

    @Bean
    public SpringCamelContext camelContext() throws Exception {
        SpringCamelContext camelContext = new SpringCamelContext(applicationContext);
        camelContext.addRoutes(applicationContext.getBean(RecordProcessor.class));
        camelContext.addRoutes(applicationContext.getBean(SandboxRoute.class));
        return camelContext;

    }

    @Bean
    public SandboxService sandboxService() {
        return new SandboxService();
    }

    @Bean
    public GetAllTheRecords getAllTheRecords() {
        return new GetAllTheRecords();
    }

    @Bean
    public SandboxWorker sandboxWorker() {
        return new SandboxWorker();
    }

    @Bean
    public SandboxRoute sandboxRoute() {
        return new SandboxRoute();
    }

    @Bean
    RecordProcessor recordProcessor() {
        return new RecordProcessor();
    }
}

SandboxRouteTest.java:

package sandbox;

import org.apache.camel.builder.AdviceWithRouteBuilder;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class SandboxRouteTest extends CamelTestSupport {

    @Override
    protected RouteBuilder createRouteBuilder() {
        return new SandboxRoute();
    }

    @Before
    public void mockEndpoints() throws Exception {
        AdviceWithRouteBuilder mockAdvice = new AdviceWithRouteBuilder() {
            @Override
            public void configure() throws Exception {
                interceptSendToEndpoint("direct:RecordProcessor").skipSendToOriginalEndpoint().to("mock:foo");
            }
        };
        context.getRouteDefinition("1").adviceWith(context, mockAdvice);
    }

    @Test
    public void testSandboxRoute() {
        System.out.println("Hello world");
    }
}

例外:

org.apache.camel.FailedToCreateRouteException: Failed to create route route1 at: >>> process[ref:getAllTheRecords] <<< in route: Route(route1)[[From[direct:ProcessTheRecords]] -> [process[r... because of No bean could be found in the registry for: getAllTheRecords of type: org.apache.camel.Processor
at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:1028)
at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:185)
at org.apache.camel.impl.DefaultCamelContext.startRoute(DefaultCamelContext.java:841)
at org.apache.camel.impl.DefaultCamelContext.startRouteDefinitions(DefaultCamelContext.java:2895)
at org.apache.camel.impl.DefaultCamelContext.doStartCamel(DefaultCamelContext.java:2618)
at org.apache.camel.impl.DefaultCamelContext.access$000(DefaultCamelContext.java:167)
at org.apache.camel.impl.DefaultCamelContext$2.call(DefaultCamelContext.java:2467)
at org.apache.camel.impl.DefaultCamelContext$2.call(DefaultCamelContext.java:2463)
at org.apache.camel.impl.DefaultCamelContext.doWithDefinedClassLoader(DefaultCamelContext.java:2486)
at org.apache.camel.impl.DefaultCamelContext.doStart(DefaultCamelContext.java:2463)
at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:61)
at org.apache.camel.impl.DefaultCamelContext.start(DefaultCamelContext.java:2432)
at org.apache.camel.test.junit4.CamelTestSupport.startCamelContext(CamelTestSupport.java:477)
at org.apache.camel.test.junit4.CamelTestSupport.doSetUp(CamelTestSupport.java:311)
at org.apache.camel.test.junit4.CamelTestSupport.setUp(CamelTestSupport.java:217)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.apache.camel.NoSuchBeanException: No bean could be found in the registry for: getAllTheRecords of type: org.apache.camel.Processor
at org.apache.camel.util.CamelContextHelper.mandatoryLookup(CamelContextHelper.java:159)
at org.apache.camel.impl.DefaultRouteContext.mandatoryLookup(DefaultRouteContext.java:151)
at org.apache.camel.model.ProcessDefinition.createProcessor(ProcessDefinition.java:97)
at org.apache.camel.model.ProcessorDefinition.makeProcessor(ProcessorDefinition.java:505)
at org.apache.camel.model.ProcessorDefinition.addRoutes(ProcessorDefinition.java:217)
at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:1025)
... 43 more

1 个答案:

答案 0 :(得分:0)

覆盖方法CamelTestSupport#createRegistry并以这种方式添加处理器:

@Override
protected JndiRegistry createRegistry() throws Exception {
    JndiRegistry registry =  super.createRegistry();
    registry.bind("getAllTheRecords", new GetAllTheRecords());
    return registry;
}

您遇到的下一个问题是,routeId="1"没有注册路线,您只有routeId="route1"的路线。 因此,将context.getRouteDefinition("1")更改为context.getRouteDefinitions().get(0)context.getRouteDefinition("route1")