ひ孫

犬のこととか書いていきたい

MRUnitいろいろ

Hadoopのテストケースを書くとき、MapやReduceのテストというのは結構書きづらかった。
ちょっと調べたら、MRUnitというのがあるので使ってみた。

基本的なセットアップなんかや利用サンプルはぐぐればたくさん出てくるので
自分で調べても出なかったようなこととかまとめてみる。

addOutputとwithOutputの違い

これ何が違うんだろうと思ったけど基本的に動作は一緒らしい。
違いはaddOutputはvoidを返すのに対してwithOutputは自身を返す。
つまりwithOutputだとメソッドチェーン的な感じに書けるっぽい
コードで書くと

// addOutputで書く場合
reduceDriver.addOutput(new Text("hello"), new Text("1"))
reduceDriver.addOutput(new Text("world"), new Text("1"))
reduceDriver.addOutput(new Text("candy"), new Text("2"));
// withOutputで書く場合
reduceDriver.withOutput(new Text("hello"), new Text("1"))
            .withOutput(new Text("world"), new Text("1"))
            .withOutput(new Text("candy"), new Text("2"));

みたいな。withInput,addInputも同様

runとrunTest

runTest()は名前の通り上記のwithOutputやaddOutputをして、入っているものと比べて違ったら失敗としてエラーを返す。
基本的にはこれを使うことになる。*1
もちろんこれが普通なのはいいんだけ「この一部の結果さえあってりゃいいんだよなー」みたいなこともある。*2 *3

そんな時はrun()がよい。
これはwithOutputのチェックをせずにただ単純に結果が返ってくる。
例えばhelloとworldの結果はチェックしたいけどそれ以外はとりあえずどうなっててもいいというテストを書きたかったら

       List<Pair<Text, Text>> expectPair = new ArrayList<Pair<Text,Text>>();
       expectPair.add(new Pair(new Text("hello"), new Text("1"));
       expectPair.add(new Pair(new Text("world"), new Text("1"));
       List<Pair<Text, Text>> resultPair = reduceDriver.run();
       for (Pair<Text, Text> expectPair : expect) {
            boolean hasEqualPair = false;
            for (Pair<Text, Text> resultPair : result) {
                if(expectPair.equals(resultPair)){
                    hasEqualPair = true;
                }
            }
            //一致するものがなかったら失敗にする
            if(hasEqualPair == false){
                fail();
            }
        }

みたいな。

*1:ちなみにrunTestの第一引数がorderMatterとなっているのでrunTest(false)として実行すれば順序は無視されるっぽい

*2:あんまりないかも。

*3:自分の場合は余分な合算値の情報なんかをだらだら出していることとかがあったのでその場合にちょっとだるいこととかがあった