簡體   English   中英

使用Apache Camel對FTP使用者進行單元測試

[英]Unit testing FTP consumer with Apache Camel

我有以下路線。 在單元測試中,由於我沒有可用的FTP服務器,我想使用camel的測試支持並向"ftp://hostname/input"發送無效消息並驗證它是否失敗並路由到"ftp://hostname/error"

我瀏覽了主要討論使用“mock:”端點的文檔,但我不確定如何在這種情況下使用它。

public class MyRoute extends RouteBuilder
{
    @Override
    public void configure()
    {
        onException(EdiOrderParsingException.class).handled(true).to("ftp://hostname/error");

        from("ftp://hostname/input")
            .bean(new OrderEdiTocXml())
            .convertBodyTo(String.class)
            .convertBodyTo(Document.class)
            .choice()
            .when(xpath("/cXML/Response/Status/@text='OK'"))
            .to("ftp://hostname/valid").otherwise()
            .to("ftp://hostname/invalid");
    }
}

正如Ben所說,您可以設置FTP服務器並使用真實組件。 可以嵌入FTP服務器,也可以在內部設置FTP服務器。 后者更像是集成測試,您可以在其中擁有專用的測試環境。

Camel在其測試工具包中非常靈活,如果您想構建一個不使用真實FTP組件的單元測試,那么您可以在測試之前替換它。 例如,在您的示例中,您可以將路由的輸入端點替換為直接端點,以便更容易向路徑發送消息。 然后你可以使用攔截器攔截發送到ftp端點,並繞過消息。

部分測試工具包的建議提供了以下功能: http//camel.apache.org/advicewith.html 並且還在Camel in action book的第6章中討論,例如6.3節,討論模擬錯誤。

在你的例子中,你可以做一些類似的事情

public void testSendError() throws Exception {
    // first advice the route to replace the input, and catch sending to FTP servers
    context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() {
        @Override
        public void configure() throws Exception {
            replaceFromWith("direct:input");

            // intercept valid messages
            interceptSendToEndpoint("ftp://hostname/valid")
                .skipSendToOriginalEndpoint()
                .to("mock:valid");

            // intercept invalid messages
            interceptSendToEndpoint("ftp://hostname/invalid")
                .skipSendToOriginalEndpoint()
                .to("mock:invalid");
        }
    });

     // we must manually start when we are done with all the advice with
    context.start();

    // setup expectations on the mocks
    getMockEndpoint("mock:invalid").expectedMessageCount(1);
    getMockEndpoint("mock:valid").expectedMessageCount(0);

    // send the invalid message to the route
    template.sendBody("direct:input", "Some invalid content here");

    // assert that the test was okay
    assertMockEndpointsSatisfied();
}

從Camel 2.10開始,我們將使用建議進行攔截和模擬更容易。 我們還介紹了一個存根組件。 http://camel.apache.org/stub

看看MockFtPServer

<dependency>
    <groupId>org.mockftpserver</groupId>
    <artifactId>MockFtpServer</artifactId>
    <version>2.2</version>
    <scope>test</scope>
</dependency>

有了這個,您可以模擬各種行為,如權限問題等:

例:

fakeFtpServer = new FakeFtpServer();

fakeFtpServer.setServerControlPort(FTPPORT);

FileSystem fileSystem = new UnixFakeFileSystem();
fileSystem.add(new DirectoryEntry(FTPDIRECTORY));
fakeFtpServer.setFileSystem(fileSystem);
fakeFtpServer.addUserAccount(new UserAccount(USERNAME, PASSWORD, FTPDIRECTORY));

...

assertTrue("Expected file to be transferred", fakeFtpServer.getFileSystem().exists(FTPDIRECTORY + "/" + FILENAME)); 

看看這個單元測試以及同一目錄中的那些...他們將向您展示如何站立本地FTP服務器進行測試以及如何使用CamelTestSupport來驗證針對它的場景等...

示例單元測試...

https://svn.apache.org/repos/asf/camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FromFileToFtpTest.java

這擴展了這個測試支持類......

https://svn.apache.org/repos/asf/camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpsServerTestSupport.java

在我們的項目中,我們不創建模擬FTP服務器來測試路由,但我們使用可由file Camel Component替換的屬性進行本地開發和單元測試。

您的代碼如下所示:

public class MyRoute extends RouteBuilder
{
    @Override
    public void configure()
    {
        onException(EdiOrderParsingException.class)
          .handled(true)
          .to("{{myroute.error}}");

        from("{{myroute.input.endpoint}}")
            .bean(new OrderEdiTocXml())
            .convertBodyTo(String.class)
            .convertBodyTo(Document.class)
            .choice()
              .when(xpath("/cXML/Response/Status/@text='OK'"))
                .to("{{myroute.valid.endpoint}}}")
              .otherwise()
                .to("{{myroute.invalid.endpoint}}");
    }
}

在本地和系統測試中,我們使用屬性文件中聲明的文件端點:

myroute.input.endpoint=file:/home/user/myproject/input
myroute.valid.endpoint=file:/home/user/myproject/valid
myroute.invalid.endpoint=file:/home/user/myproject/invalid
myroute.error=file:/home/user/myproject/error

或者在JUnit CamelTestSupport中,您可以使用useOverridePropertiesWithPropertiesComponent方法設置要覆蓋的屬性。

作為替代方案,您也可以使用“直接”路線,但是您可能會錯過一些可以通過單元測試進行測試的文件選項。

我們只通過設置如下屬性來測試與真實系統的FTP連接:

myroute.input.endpoint=ftp://hostname/input
myroute.valid.endpoint=ftp://hostname/valid
myroute.invalid.endpoint=ftp://hostname/invalid
myroute.error=ftp://hostname/error

通過這種方式,您還可以為生產服務器提供不同的配置,以區別於集成測試環境。

生產環境的屬性示例:

myroute.input.endpoint=ftp://hostname-prod/input
myroute.valid.endpoint=ftp://hostname-prod/valid
myroute.invalid.endpoint=ftp://hostname-prod/invalid
myroute.error=ftp://hostname-prod/error

在我看來,使用文件端點來簡化JUnit代碼是完全可以接受的,它只會測試路由而不是連接。

測試連接更像是集成測試,應該在與真實外部系統連接的真實服務器上執行(在您的情況下是FTP服務器,但也可以是其他端點/系統)。

通過使用屬性,您還可以為每個環境配置不同的URL(例如:我們有3個測試環境和一個生產環境,所有環境都有不同的端點)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM