我正在用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测试中这样做,否则我必须创建 `/geo/GeoLite2-City.mmdb` 在我的本地机器和Jenkins这不是理想的。我在想办法让我的测试在使用时通过 `new File(GEO_DB)` 而不是 `getClass().getResourceAsStream('./geo/GeoLite2-City.mmdb')` 因为
getClass().getResourceAsStream('./geo/GeoLite2-City.mmdb')
在hadoop中不起作用。
如果我运行junit测试,它会失败,因为我没有 `/geo/GeoLite2-City.mmdb` 在我的本地机器上。
有什么我能克服的吗?我只希望我的测试能够通过,而不改变要使用的代码 `getClass().getResourceAsStream` 我不能,如果/否则,因为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")));
}
如果我从资源文件夹读取数据库文件,它就会工作。这就是为什么我要忽略
3条答案
按热度按时间zlwx9yxi1#
你没有。你的问题在措辞上自相矛盾。资源不是文件,也不存在于文件系统中。您可以将文件与jar分开分发,并将其用作
File
或者将其包含在jar中并将其用作资源。不是两者都有。你必须下定决心。toiithl62#
您必须使文件位置可配置。e、 g.通过构造函数注入。e、 你可以创建一个非默认的构造函数来进行测试。
现在您可以从该资源创建一个文件,并在测试中使用该文件。
temporaryfolder是一个junit规则,它删除在测试期间创建的所有文件。
您可以使用
hasToString
匹配器。如果测试失败,这将为您提供更详细的信息(而且你必须读/写更少的代码。)jw5wzhpr3#
另外,你的整个代码看起来是不可测试的。
每次在生产代码中直接调用new时,都会阻止依赖注入;因此,测试代码变得更加困难。
关键是不要打电话
new File()
在生产代码中。相反,您可以使用一个工厂,它为您提供一个“随时可用”的databasereader对象。然后你可以测试你的工厂做正确的事情;您可以在测试此代码时模拟工厂(以返回模拟的数据库读取器)。因此,这一个文件示例只是您的“测试问题”的顶部。
老实说:不要先写生产代码。做tdd:先写测试用例;您将很快了解到,您在这里展示的这种产品代码确实很难测试。当您应用tdd时,您将从“测试Angular ”开始,并且您将创建真正可测试的产品代码。