Java 测试一个sFTP端点

Java 测试一个sFTP端点,java,testing,apache-camel,Java,Testing,Apache Camel,我有以下路线: public void configure() throws Exception { from(ftpEndpoint) .routeId("import-lib-files") .log(INFO, "Processing file: '${headers.CamelFileName}' from Libri-FTP") .choice() .when(method(isFilenameAlreadyImp

我有以下路线:

public void configure() throws Exception {
    from(ftpEndpoint)
        .routeId("import-lib-files")
        .log(INFO, "Processing file: '${headers.CamelFileName}' from Libri-FTP")
        .choice()
        .when(method(isFilenameAlreadyImported))
            .log(DEBUG, "'${headers.CamelFileName}' is already imported.")
        .endChoice()
        .otherwise()
        .bean(method(unzipLibFile))
        .bean(method(persistFilename))
        .log(DEBUG, "Import file '${headers.CamelFileName}'.")
        .endChoice()
    .end()
    .end();
}
unzipLibFile
处理器bean中,来自ftp的文件被解压缩并写入HD

我想测试(集成测试)这条路线,比如:

  • 将文件复制到ftp
  • 开始路线
  • 评估“结果”
我喜欢:

  @Before
  public void setUp() throws Exception {
    // delete test-file from sftp
    final String uploaded = ftpPath + "/" + destination + "/libri-testfile.zip";
    final File uploadedFile = new File(uploaded);
    uploadedFile.delete();

    // delete unzipped test-file
    final String unzippedFile = unzipped + "/libri-testfile.xml";
    final File expectedFile = new File(unzippedFile);
    expectedFile.delete();

    // delete entries from db
    importedLibFilenameRepository.deleteAll();

    // copy file to ftp
    final File source =
    new ClassPathResource("vendors/references/lib.zip/libri-testfile.zip").getFile();
    final String target = ftpPath + "/" + destination + "/libri-testfile.zip";
    FileUtils.copyFile(new File(source.getAbsolutePath()), new File(target));
  }


  @Test
  @Ignore
  public void testStuff() throws Exception {
    // Well here is a problem, I can't fix at the moment
    // the Camel-Context within the SpringContext get started when the tests starts
    // during this process the Camel-Routes are executed and because i copied the file to
    // the ftp all is fine... but I don't want to have a sleep in a test, I want to start the
    // route (like commented code beneath the sleep)
    Thread.sleep(2000);

//    final Map<String, Object> headers = Maps.newHashMap();
//    headers.put("CamelFileName", "libri-testfile.zip");
//
//    final File file =
//        new ClassPathResource("vendors/references/lib.zip/libri-testfile.zip").getFile();
//    final GenericFile<File> genericFile =
//        FileConsumer.asGenericFile(file.getParent(), file, StandardCharsets.UTF_8.name(), false);
//
//    final String uri = libFtpConfiguration.getFtpEndpoint();
//    producer.sendBodyAndHeaders(uri, InOut, genericFile, headers);

    // test if entry was made in the database
    final List<ImportedLibFilename> filenames = importedLibFilenameRepository.findAll();
    assertThat(filenames).usingElementComparatorIgnoringFields("id", "timestamp")
    .containsExactly(expectedFilename("libri-testfile.zip"));

    // test if content of unzipped file is valid
    final String expected = unzipped + "/libri-testfile.xml";
    final Path targetFile = Paths.get(expected);
    final byte[] encoded = Files.readAllBytes(targetFile);
    final String actualFileContent = new String(encoded, Charset.defaultCharset());

    final String expectedFileContent = "This is my little test file for Libri import";
    assertThat(actualFileContent).isEqualTo(expectedFileContent);
  }

  private ImportedLibFilename expectedFilename(final String filename) {
    final ImportedLibFilename entity = new ImportedLibFilename();
    entity.setFilename(filename);
    return entity;
  }
@之前
public void setUp()引发异常{
//从sftp中删除测试文件
上传的最终字符串=ftpPath+“/”+destination+“/libri testfile.zip”;
最终文件上传文件=新文件(上传);
uploadedFile.delete();
//删除解压缩的测试文件
最后一个字符串unzippedFile=unzipped+“/libri testfile.xml”;
最终文件expectedFile=新文件(解压缩文件);
expectedFile.delete();
//从数据库中删除条目
importedLibFilenameRepository.deleteAll();
//将文件复制到ftp
最终文件源=
新的ClassPathResource(“vendors/references/lib.zip/libri testfile.zip”).getFile();
最终字符串target=ftpPath+“/”+destination+“/libri testfile.zip”;
copyFile(新文件(source.getAbsolutePath()),新文件(target));
}
@试验
@忽略
public void testStuff()引发异常{
//嗯,有个问题,我现在无法解决
//测试开始时,SpringContext中的驼峰上下文开始
//在此过程中,将执行骆驼路由,因为我将文件复制到
//ftp一切正常…但我不想在考试中睡觉,我想开始考试
//路由(如睡眠下的注释代码)
《睡眠》(2000年);
//最终映射头=Maps.newHashMap();
//headers.put(“CamelFileName”、“libri testfile.zip”);
//
//最终文件=
//新的ClassPathResource(“vendors/references/lib.zip/libri testfile.zip”).getFile();
//最终GenericFile GenericFile=
//FileConsumer.asGenericFile(file.getParent(),file,StandardCharsets.UTF_8.name(),false);
//
//最后一个字符串uri=libftpcConfiguration.getFtpEndpoint();
//sendboyandheaders(uri、InOut、genericFile、headers);
//测试是否在数据库中进行了输入
最终列表文件名=importedLibFilenameRepository.findAll();
assertThat(文件名)。usingElementComparatorIgnoringFields(“id”、“时间戳”)
.containsExactly(预期文件名(“libri testfile.zip”);
//测试解压缩文件的内容是否有效
应为最终字符串=解压缩+“/libri testfile.xml”;
最终路径targetFile=Path.get(预期);
最终字节[]编码=Files.readAllBytes(targetFile);
最终字符串actualFileContent=新字符串(编码,Charset.defaultCharset());
最后一个字符串expectedFileContent=“这是我用于Libri导入的小测试文件”;
assertThat(实际文件内容).isEqualTo(预期文件内容);
}
private ImportedLibFilename expectedFilename(最终字符串文件名){
最终ImportedLibFilename实体=新的ImportedLibFilename();
entity.setFilename(文件名);
返回实体;
}
问题是:
所有驼峰路由都自动启动,因为我将文件复制到FTP,所以测试为绿色。但我在考试时睡了一觉,这是我不想要的。我不想要骆驼路线开始,只开始我需要的路线

我的问题是:

  • 如何防止骆驼路线自动启动
  • 注释代码(在测试方法中)是手动启动路由的正确方法吗
  • 使用ftp测试驼峰路由的最佳实践是什么
  • 在路由中使用
    .autoStartup(您的变量)
    ,使其启动可配置。在正常环境中将变量设置为
    true
    ,在测试用例中将变量设置为
    false
  • 我看不到启动路线的代码
  • 好吧,退后一步。考虑拆分FTP路由。出于测试和其他原因:
  • 例如,将路由拆分为FTP和处理路由。第一个只进行FTP传输,然后将收到的消息发送到处理路由(例如
    direct:
    route)

    好处:

    • :两条路线只做一件事,你可以集中精力
    • 可测试性:通过向处理路由的
      直接:
      端点发送消息,可以轻松测试处理路由。测试也可以关注一件事
    • 可扩展性:想象一下有一个新的输入通道(JMS、HTTP等等)。然后,您只需添加另一个输入路由,它也会发送到您的处理路由。完成了
    当您确实想要测试从FTP文件删除到结束的整个过程时,请考虑使用或类似的工具。驼峰路线测试(在我看来)是一种“驼峰路线的单元测试”,而不是完全集成测试

  • 在路由中使用
    .autoStartup(您的变量)
    ,使其启动可配置。在正常环境中将变量设置为
    true
    ,在测试用例中将变量设置为
    false
  • 我看不到启动路线的代码
  • 好吧,退后一步。考虑拆分FTP路由。出于测试和其他原因:
  • 例如,将路由拆分为FTP和处理路由。第一个只进行FTP传输,然后将收到的消息发送到处理路由(例如
    direct:
    route)

    好处:

    • :两条路线只做一件事,你可以集中精力
    • 可测试性:通过向处理路由的
      直接:
      端点发送消息,可以轻松测试处理路由。测试也可以关注一件事
    • 可扩展性:想象一下有一个新的输入通道(JMS、HTTP等等)。然后,您只需添加另一个输入路由,它也会发送到您的处理路由。完成了 @Override public void configure() throws Exception { // @formatter:off from(endpoint) .setHeader("Address", constant(address)) .log(INFO, "Import Libri changeset: Consuming from '${headers.Address}' the file '${headers.CamelFileName}'.") .to("direct:import-new-file"); // @formatter:on }
        @Override
        public void configure() throws Exception {
          // @formatter:off
          from("direct:import-new-file")
              .choice()
                .when(method(isFilenameAlreadyImported))
                .log(TRACE, "'${headers.CamelFileName}' is already imported.")
              .endChoice()
              .otherwise()
                .log(TRACE, "Import file '${headers.CamelFileName}'.")
                .multicast()
                .to("direct:persist-filename", "direct:unzip-file")
              .endChoice()
            .end()
          .end();
          // @formatter:on
        }
      
        @Override
        public void configure() throws Exception {
          // @formatter:off
            from("direct:persist-filename")
              .log(TRACE, "Try to write filename '${headers.CamelFileName}' to database.")
              .bean(method(persistFilename))
            .end();
          // @formatter:on
        }
      
        @Override
        public void configure() throws Exception {
          // @formatter:off
            from("direct:unzip-file")
              .log(TRACE, "Try to unzip file '${headers.CamelFileName}'.")
              .bean(method(unzipFile))
            .end();
          // @formatter:on
        }
      
        @Test
        public void testRoute_validExtractedFile() throws Exception {
          final File source = ZIP_FILE_RESOURCE.getFile();
          producer.sendBodyAndHeaders(URI, InOut, source, headers());
      
          final String actual = getFileContent(unzippedPath, FILENAME);
          final String expected = "This is my little test file for Libri import";
          assertThat(actual).isEqualTo(expected);
        }
      
        @Test
        public void testRoute_databaseEntryExists() throws Exception {
          final File source = ZIP_FILE_RESOURCE.getFile();
          producer.sendBodyAndHeaders(URI, InOut, source, headers());
      
          final List<ImportedFilename> actual = importedFilenameRepository.findAll();
          final ImportedFilename expected = importedFilename(ZIPPED_FILENAME);
          assertThat(actual).usingElementComparatorIgnoringFields("id", "timestamp")
          .containsExactly(expected);
        }
      
        private String getFileContent(final String path, final String filename) throws IOException {
          final String targetFile = path + "/" + filename;
          final byte[] encodedFileContent = Files.readAllBytes(Paths.get(targetFile));
          return new String(encodedFileContent, Charset.defaultCharset());
        }
      
        private Map<String, Object> headers() {
          final Map<String, Object> headers = Maps.newHashMap();
          headers.put("CamelFileName", ZIPPED_FILENAME);
          return headers;
        }