With Apache MRUnit我能夠在集羣上運行MapReduce程序之前在本地單元測試我的MapReduce程序。MapReduce單元測試無法模擬DistributedCache.getLocalCacheFiles
我的程序需要從DistributedCache中讀取,所以我把DistributedCache.getLocalCacheFiles
換成了我的單元測試中的mock。我設置了一個存根,這樣當該方法不會被調用,而是返回一個本地路徑。但事實證明,該方法被調用並拋出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);
}
}
我可以映射器的設置增加了一個標誌方法,以便在測試時讀取本地路徑,但我確實想分割測試來自我的MapReduce程序的代碼。
我是模擬測試和MRUnit的新手,所以在我的程序中可能會有新手bug。請指出錯誤,我會解決它們,並在下面發佈我的更新。
拋出相同的'FileNotFoundException' – manuzhang 2013-03-28 05:06:40
請參閱我的編輯 – Gopi 2013-03-28 05:12:06
這將混合我的mapreduce程序的測試代碼。那麼爲什麼首先使用嘲諷?如果標誌爲真,我可以通過構造函數傳遞一個標誌並從'setup'的本地路徑中讀取。 – manuzhang 2013-03-28 16:01:21