gpt4 book ai didi

java - MapReduce 单元测试无法模拟 DistributedCache.getLocalCacheFiles

转载 作者:行者123 更新时间:2023-11-29 09:04:40 24 4
gpt4 key购买 nike

Apache MRUnit在集群上运行之前,我能够在本地对我的 MapReduce 程序进行单元测试。

我的程序需要读取 DistributedCache所以我将 DistributedCache.getLocalCacheFiles 包装在我 mock 的类中在我的单元测试中。我设置了一个 stub ,以便在不调用方法时返回本地路径。但结果是该方法被调用并抛出 FileNotFoundException

这是我的 MapReduce 程序的样子

public class TopicByTime implements Tool {
private static Map<String, String> topicList = null;

public static void main(String[] args) throws Exception {
System.exit(ToolRunner.run(new TopicByTime(), args));
}

@Override
public int run(String[] args) throws Exception {
Job job = new Job();
/* Job setup */
DistributedCache.addCacheFile(new URI(/* path on hdfs */), conf);
job.waitForCompletion(true);
return 0;
}

protected static class TimeMapper extends Mapper<LongWritable, Text, Text, Text> {
@Override
public void setup(Context context) throws IOException, InterruptedException {
DistributedCacheClass cache = new DistributedCacheClass();
Path[] localPaths = cache.getLocalCacheFiles(context.getConfiguration());
if (null == localPaths || 0 == localPaths.length) {
throw new FileNotFoundException("Distributed cached file not found");
}
topicList = Utils.loadTopics(localPaths[0].toString());

}

@Override
public void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
/* do map */
}
}

/* Reducer and overriding methods */
}

还有我的测试程序

public class TestTopicByTime {

@Before
public void setUp() throws IOException {
Path[] localPaths = { new Path("resource/test/topic_by_time.txt")};
Configuration conf = Mockito.mock(Configuration.class);
DistributedCacheClass cache = Mockito.mock(DistributedCacheClass.class);
when(cache.getLocalCacheFiles(conf)).thenReturn(localPaths);
}

@Test
public void testMapper() {
}

@Test
public void testReducer() {
}

@Test
public void testMapReduce() {
}
}

DistributedCacheClass 是一个简单的包装器

public class DistributedCacheClass {
public Path[] getLocalCacheFiles(Configuration conf) throws IOException {
return DistributedCache.getLocalCacheFiles(conf);
}
}

我可以在 Mapper 的设置方法中添加一个标志,以便在测试时读取本地路径,但我确实想从我的 MapReduce 程序中拆分测试代码。

我是模拟测试和 MRUnit 的新手,所以我的程序中可能存在新手错误。请指出错误,我会修复它们并在下面发布我的更新。

最佳答案

在您的 TestTopicByTime.setUp() 中更改行

when(cache.getLocalCacheFiles(conf)).thenReturn(localPaths);

when(cache.getLocalCacheFiles(any(Configuration.class))).thenReturn(localPaths);

在模拟时,参数匹配为相等。它们在您的情况下不相等,因为您在代码中传递的实际上下文与您在测试中创建的模拟配置不匹配。因此,您需要使用 Argument Matcher any() 来避免精确的对象比较。

编辑:此外,在您的 TimeMapper.setup() 中,您正在创建一个新的缓存,DistributedCacheClass cache = new DistributedCacheClass();

所以您根本没有使用您创建的模拟对象。您必须能够将您的模拟缓存注入(inject)到 TimeMapper 中。您可以将缓存对象从外部传递给 TimeMapper,最好是通过构造函数。所以在您的测试中,您可以向它传递一个模拟缓存对象。

关于java - MapReduce 单元测试无法模拟 DistributedCache.getLocalCacheFiles,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15674229/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com