camel unit test with cametestsupport, template is always null

妖精的绣舞 提交于 2019-12-11 04:20:02

问题


I am doing a simple unit test with camel. All I want to do is to read a json from a file (under resources), send it to a java class for validation - this is the route that I am trying to test. Whatever I do, the template (which I use to sendBody(json) is always null. Here is my code

public class RouteTests extends CamelTestSupport {

    @EndpointInject(uri = "mock:result")
    protected MockEndpoint resultEndpoint;

    @Produce(uri = "direct:start")
    protected ProducerTemplate template;

    @Autowired
    JSONObject testJson;

    @Before
    public void setUp() throws Exception {
        try {
            final ObjectMapper objectmapper = new ObjectMapper();
            final ClassLoader loader = Thread.currentThread().getContextClassLoader();
            final InputStream stream = loader.getResourceAsStream("test.json");
            testJson = new JSONObject ((Map)objectmapper.readValue(stream, Map.class));
            //start camel
            context = new DefaultCamelContext();
            context.addRoutes(createRouteBuilder());
            context.start();
        } catch (IOException e) {
        }
    }

    @Test
    public void testSendMatchingMessage() throws Exception {
//        resultEndpoint.expectedBodiesReceived(expectedBody);
        resultEndpoint = getMockEndpoint("mock:result");
//        resultEndpoint = context.getEndpoint("mock:result", MockEndpoint.class);
        resultEndpoint.expectedMessageCount(1);
        template.sendBody("direct:start", testJson);
        resultEndpoint.assertIsSatisfied();
    }

    @Override
    protected RouteBuilder createRouteBuilder() {
        return new RouteBuilder() {
            public void configure() {
                from("direct:start")
                        .filter().method(ValidationProcessor.class, "validate")
                        .to("mock:result");
            }
        };
    }

    @Override
    protected JndiRegistry createRegistry() throws Exception {
        JndiRegistry jndi = super.createRegistry();
        jndi.bind("ValidationProcessor", new ValidationProcessor",());

        return jndi;
    }
}

Problems I faced: 1. Initially the result end point also was always null. (I used http://svn.apache.org/repos/asf/camel/trunk/components/camel-test/src/test/java/org/apache/camel/test/patterns/FilterTest.java for reference). Then I had to do an explicit

resultEndpoint = getMockEndpoint("mock:result");

to resolve that.

  1. Then I read that I had to override the createRegistry but I did not know how to bind. I just used the name of my validation class but I dont know if this is right.

But the template is always null. The NPE is at

template.sendBody("direct:start", testJson);

I have been trying to resolve this for a long time and I finally turn to you guys for help. Really am tired :(

Please also point me to some reading if necessary. The reference code that apache camel docs link to did not even have the starting of the camel that I do in the setUp method. Not even sure if it is needed. Please help !

Ananth


回答1:


I think you've missed out on a lot of the really helpful stuff that CamelTestSupport does for you. It has its own setUp method that you should override. I believe your test should really look something like this:

public class RouteTests extends CamelTestSupport {

    private JSONObject testJson;

    @Override
    public void setUp() throws Exception {
        // REALLY important to call super
        super.setUp();

        ObjectMapper objectmapper = new ObjectMapper();
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        InputStream stream = loader.getResourceAsStream("test.json");
        testJson = new JSONObject(objectmapper.readValue(stream, Map.class));
    }

    @Override
    protected RouteBuilder createRouteBuilder() {
        return new RouteBuilder() {
            @Override
            public void configure() {
                from("direct:start")
                        .filter().method(ValidationProcessor.class, "validate")
                        .to("mock:result");
            }
        };
    }

    @Test
    public void testSendMatchingMessage() throws Exception {
        MockEndpoint resultEndpoint = getMockEndpoint("mock:result");
        resultEndpoint.expectedMessageCount(1);
        template.sendBody("direct:start", testJson);
        resultEndpoint.assertIsSatisfied();
    }
}

Actually I would remove the override of setUp altogether and put the reading of the test data in to the test method itself. Then it's clear what the data is being used for and you can eliminate the testJson field.

public class RouteTests extends CamelTestSupport {

    @Override
    protected RouteBuilder createRouteBuilder() {
        return new RouteBuilder() {
            @Override
            public void configure() {
                from("direct:start")
                        .filter().method(ValidationProcessor.class, "validate")
                        .to("mock:result");
            }
        };
    }

    @Test
    public void testSendMatchingMessage() throws Exception {
        ObjectMapper objectmapper = new ObjectMapper();
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        InputStream stream = loader.getResourceAsStream("test.json");
        JSONObject testJson = new JSONObject(objectmapper.readValue(stream, Map.class));

        MockEndpoint resultEndpoint = getMockEndpoint("mock:result");
        resultEndpoint.expectedMessageCount(1);
        template.sendBody("direct:start", testJson);
        resultEndpoint.assertIsSatisfied();
    }
}

There, much simpler.




回答2:


try to create the producertemplate from the camel context as so:

public class RouteTests extends CamelTestSupport {

@EndpointInject(uri = "mock:result")
protected MockEndpoint resultEndpoint;

protected ProducerTemplate template;

@Autowired
JSONObject testJson;

@Before
public void setUp() throws Exception {
    try {
        final ObjectMapper objectmapper = new ObjectMapper();
        final ClassLoader loader = Thread.currentThread().getContextClassLoader();
        final InputStream stream = loader.getResourceAsStream("test.json");
        testJson = new JSONObject ((Map)objectmapper.readValue(stream, Map.class));
        //start camel
        context = new DefaultCamelContext();
        context.addRoutes(createRouteBuilder());
        context.start();
        template = context.createProducerTemplate();
    } catch (IOException e) {
    }
}

@Test
public void testSendMatchingMessage() throws Exception {
    //resultEndpoint.expectedBodiesReceived(expectedBody);
    resultEndpoint = getMockEndpoint("mock:result");
    //resultEndpoint = context.getEndpoint("mock:result", MockEndpoint.class);
    resultEndpoint.expectedMessageCount(1);
    template.sendBody("direct:start", testJson);
    resultEndpoint.assertIsSatisfied();
}

@Override
protected RouteBuilder createRouteBuilder() {
    return new RouteBuilder() {
        public void configure() {
            from("direct:start")
                    .filter().method(ValidationProcessor.class, "validate")
                    .to("mock:result");
        }
    };
}

@Override
protected JndiRegistry createRegistry() throws Exception {
    JndiRegistry jndi = super.createRegistry();
    jndi.bind("ValidationProcessor", new ValidationProcessor());

    return jndi;
}

}

So in your setUp() just add:

template = context.createProducerTemplate();

and remove @Produce(uri = "direct:start")



来源:https://stackoverflow.com/questions/49118176/camel-unit-test-with-cametestsupport-template-is-always-null

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!