java - 如何在 Java 项目中包含一个资源文件以仅与 new File() 一起使用?

标签 java hadoop junit apache-pig

我正在使用 Java 为 Pig 编写 UDF。它工作正常,但 Pig 没有给我分离环境的选项。我的 Pig 脚本正在做的是从 IP 地址获取地理位置。

这是我在地理位置部分的代码。

private static final String GEO_DB = "GeoLite2-City.mmdb";
private static final String GEO_FILE = "/geo/" + GEO_DB;

 public Map<String, Object> geoData(String ipStr) {
        Map<String, Object> geoMap = new HashMap<String, Object>();

        DatabaseReader reader = new DatabaseReader.Builder(new File(GEO_DB)).build();
            // other stuff
    }

GeoLite2-City.mmdb 存在于 HDFS 中,这就是为什么我可以使用 /geo/GeoLite2-City.mmdb 从绝对路径引用。

但是,我不能通过我的 JUnit 测试做到这一点,或者我必须在我的本地机器和 Jenkins 上创建 /geo/GeoLite2-City.mmdb,这并不理想。我正在尝试找出一种方法让我的测试通过,同时使用 new File(GEO_DB) 而不是 getClass().getResourceAsStream('./geo/GeoLite2-City.mmdb') 因为

getClass().getResourceAsStream('./geo/GeoLite2-City.mmdb')

在 Hadoop 中不起作用。

如果我运行 Junit 测试,它会失败,因为我的本地计算机上没有 /geo/GeoLite2-City.mmdb

无论如何我可以克服这个问题吗?我只是希望我的测试通过而不更改使用 getClass().getResourceAsStream 的代码,我不能 if/else 解决这个问题,因为 Pig 没有给我一种方法来传递参数或也许我遗漏了什么。

这是我的 JUnit 测试

@Test
@Ignore
public void shouldGetGeoData() throws Exception {
    String ipTest = "128.101.101.101";

    Map<String, Object> geoJson = new LogLine2Json().geoData(ipTest);

    assertThat(geoJson.get("lLa").toString(), is(equalTo("44.9759")));
    assertThat(geoJson.get("lLo").toString(), is(equalTo("-93.2166")));

}

如果我从资源文件夹中读取数据库文件,它会起作用。这就是为什么我有@Ignore

最佳答案

此外,您的整个代码看起来都无法测试。

每次在生产代码中直接调用 new 时,都可以防止依赖注入(inject);从而使测试代码变得更加困难。

重点是不要在生产代码中调用 new File()。 相反,您可以使用为您提供“随时可用”的 DatabaseReader 对象的工厂。然后你可以测试你的工厂做正确的事;并且您可以在测试此代码时模拟该工厂(以返回模拟的数据库读取器)。

因此,一个文件实例只是您此处“测试问题”的首要问题。

老实说:不要先编写生产代码。做TDD:先写测试用例;您很快就会了解到,您在此处展示的此类生产代码确实很难测试。当您应用 TDD 时,您从“测试角度”开始,您将创建真正可测试的生产代码。

关于java - 如何在 Java 项目中包含一个资源文件以仅与 new File() 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36781391/

相关文章:

java - hadoop flume log4j 配置

javascript - karma 无法加载junits插件

java - 在jUnit测试中将参数传递给@Before设置

java - 使用 rc.local 在启动时自动启动一个脚本,多个 screen 启动一个 sh 文件

java - ClassLoader问题导致ClassCastException的解决方法

java - toString 应该用于复杂的操作吗?

hadoop - 在 socks 代理上访问 GCloud 资源

hadoop - Hadoop 中 Reducer 的错误输入值

java - Lucene索引和Map/Reduce搜索

java - 使用mockito模拟其余客户端类抛出空指针异常