0

我正在尝试测试这样的路线:

from("s3://bucketName")
.process(exchange -> {exchange.getIn().setHeader(Exchange.FILE_NAME,MY_FILE_NAME);})
.log("File download Successful")
.to("file:" + FILE_PATH).routeId("mys3Route");

我已经这样写了我的测试:

@Test
public void testFileMovement() throws Exception {
    AdviceWith.adviceWith(context, "mys3Route", a -> {
        a.replaceFromWith("mock:s3Location");
        a.interceptSendToEndpoint("file:" + FILE_PATH).skipSendToOriginalEndpoint()
                .to("mock:anotherLocation");
    });
    MockEndpoint mockedToEndPoint = getMockEndpoint("mock:anotherLocation");
    mockedToEndPoint.setExpectedMessageCount(1);
    template.sendBody("mock:s3Location", "Just Text");
    mockedToEndPoint.assertIsSatisfied();
    Thread.sleep(5000);
}

每当我将其作为单元测试用例运行时,都会出现此错误:

org.apache.camel.CamelExecutionException:在交易所执行期间发生异常:Exchange []

该错误似乎出现在:(org.apache.camel.impl.engine.DefaultProducerTemplate.extractResultBody(DefaultProducerTemplate.java:591)存在于骆驼依赖项中)。

关于我做错了什么以及如何纠正它的任何想法?非常感谢任何有助于解决和理解此问题的帮助。

4

1 回答 1

0

对于初学者,您可能不应该用 MockEndpoint 替换 consumer/From 端点,只需使用直接端点。MockEndpoints仅支持生产者端点(to),不应用作消费者端点(from)。MockEndpoints 旨在用作您要对消息正文、交换属性、收到的消息等内容进行断言的路线上的点。

其次,如果您使用AdviceWith,则应将isUseAdviceWithtemplate.send设置为 true 并在使用方法之前手动启动上下文。如果您是否使用 Spring Boot 注释,其设置方式会有所不同。下面的示例仅使用简单的 CamelTestSupport。

第三,您很少需要在骆驼测试中使用拦截,而是使用weaveByIdweaveByToURI和替换。在这种情况下,您最好只使用属性占位符来修复文件路径和文件名的设置方式。这样你就可以使用 junit 的 useOverridePropertiesWithPropertiesComponent 和 TemporaryFolder 功能。如果您需要读取测试文件的文件内容或将某些内容复制到测试文件夹,Apache-commons IO FileUtils 也非常方便。

在单元测试中使用 Thread.Sleep 充其量是 hacky,应该避免。对于这种情况,我认为您没有理由使用它。RouteId 最好放在路由的顶部。

例子:

package com.example;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Properties;

import org.apache.camel.RoutesBuilder;
import org.apache.camel.builder.AdviceWithRouteBuilder;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.apache.commons.io.FileUtils;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

public class ExampleTest extends CamelTestSupport {
    
    @Rule
    public TemporaryFolder temporaryFolder = new TemporaryFolder();
    File outputFolder;

    static final String FILE_NAME = "testfile.txt";

    @Test
    public void testFileMovement() throws Exception {

        context.getRouteDefinition("mys3Route")
            .adviceWith(context, new AdviceWithRouteBuilder(){

            @Override
            public void configure() throws Exception {

                replaceFromWith("direct:start");
                weaveAddLast()
                    .to("mock:result");
            } 
        });

        MockEndpoint resultMockEndpoint = getMockEndpoint("mock:result");
        resultMockEndpoint.setExpectedMessageCount(1);

        startCamelContext();
        template.sendBody("direct:start", "Just Text");

        File file = new File(outputFolder, FILE_NAME);
        assertEquals(true, file.exists());
        String fileContents = FileUtils.readFileToString(file, StandardCharsets.UTF_8);
        assertEquals("Just Text", fileContents);

        resultMockEndpoint.assertIsSatisfied();
    }

    @Override
    protected RoutesBuilder createRouteBuilder() throws Exception {
       
        return new RouteBuilder(){

            @Override
            public void configure() throws Exception {
                
                from("s3://bucketName")
                    .routeId("mys3Route")
                    .log("File download Successful")
                    .to("file:{{filepath}}?fileName={{filename}}");
            }
        };
    }

    @Override
    protected Properties useOverridePropertiesWithPropertiesComponent() {

        try {
            outputFolder = temporaryFolder.newFolder("output");
        } catch (IOException e) {
            e.printStackTrace();
        }

        Properties properties = new Properties();
        properties.put("filename", FILE_NAME);
        properties.put("filepath", outputFolder.getPath());

        return properties;
    }

    @Override
    public boolean isUseAdviceWith() {
        return true;
    }   
}
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>${commons-io.version}</version>
</dependency>
于 2022-02-14T13:32:49.753 回答