Mockito と Junit を使用した Hadoop Unit Test

まだまだ、Hadoop の勉強中です。今は Hadoop プログラムのテストおよびデバッグ方法について調べてました。

Hadoop 本 (http://oreilly.com/catalog/9780596521981)には Junit と Mockito を利用したテストの書き方が紹介されています。勉強がてら簡単なプログラムを書いてみました。

まずは、今回テストされる単語をカウントするためのマッパークラスを以下のように定義します。このクラスの map メソッドは入力文をスペースで分割してキーが単語 (Text), バリューが 1 (LongWritable) の要素を Context.write によって追加します。

import java.io.IOException;
import java.util.StringTokenizer;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

public class WordCountMapper
    extends Mapper<LongWritable, Text, Text, LongWritable> {

  @Override
  protected void map(LongWritable key, Text value,
                     Context context) throws IOException, InterruptedException {

      StringTokenizer itr = new StringTokenizer(value.toString());
      while (itr.hasMoreTokens()) {
          context.write(new Text(itr.nextToken()), new LongWritable(1));
      }
  }
}

この map メソッドが期待通り動いているのかチェックするために、以下のテストプログラムを書きました。このプログラムでは、WordCountMapper内の map メソッドで期待した出力が Context オブジェクトの write メソッドを通じて期待された回数だけ出力されているのかを verify メソッドでチェックします。

import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Mapper.Context;

import org.junit.*;
import org.junit.runner.JUnitCore;
import static org.mockito.Mockito.*;

import java.lang.InterruptedException;
import java.io.IOException;

public class WordCountMapperTest {

    public static void main(String[] args) {
        JUnitCore.main(WordCountMapperTest.class.getName());
    }

    @Test
        public void testValidInput() throws IOException, InterruptedException {
        WordCountMapper wordCountMapper = new WordCountMapper();
        Text    value   = new Text("This is a pen and that is a note.");
        Context mock_context = mock(Context.class);

        wordCountMapper.map(null, value, mock_context);

        verify(mock_context, times(1)).write(new Text("This"), new LongWritable(1));
        verify(mock_context, times(2)).write(new Text("is"), new LongWritable(1));
        verify(mock_context, times(2)).write(new Text("a"), new LongWritable(1));
        verify(mock_context, times(1)).write(new Text("pen"), new LongWritable(1));
        verify(mock_context, times(1)).write(new Text("that"), new LongWritable(1));
        verify(mock_context, times(1)).write(new Text("note."), new LongWritable(1));
    }
}