Google AdSense (text)

hidden logo stop

Moving

거지 같은 이글루스 광고노출 정책이 싫어서,
새 보금자리(http://blog.leocat.kr/)로 이사감.

[Hadoop] 테스트 MRUnit & Mockito Computer & Program

하둡 테스트를 위해 MRUnit과 Mockito를 사용한 예제([Hadoop] MRUnit,Mockito를 사용한 테스트 케이스 작성 -Mapper-)를 찾아봤다. 링크를 보면 테스트를 작성하는 내용이 잘 나와 있다. 나도 슝슝 따라 했는데.. 결과는 만족.. 그리고 MRUnit을 사용하기로 결정..

내 경우에는 Mockito를 사용하는데 문제가 좀 있었다. Driver에서 Mapper와 Reducer로 넘겨주는 정보들이 몇 개 있는데, 이 때 Configuration에 값을 설정해서 전달했다. 때문에 Configuration을 사용해야 하는데, Context를 mock으로 생성하는 Mockito의 경우는 Context.Configuration이 null이 되기 때문에 사용할 수가 없었다.

아래 테스트 코드는 주어진 텍스트를 패턴 매칭 후, 3번째 매칭된 그룹의 값을 꺼내오는 Mapper를 테스트한 것이다. Mapper에서 패턴과 그룹을 Configuration에서 가져오기 때문에 테스트 코드에서는 해당 값을 설정해 주어야 한다.

import static org.mockito.Mockito.*;

import java.io.IOException;

import kr.bestbuyer.keyword.hadoop.searchLog.mapper.QueryCountMapper;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Mapper.Context;
import org.apache.hadoop.mrunit.mapreduce.MapDriver;
import org.junit.Test;

public class ExampleTest
{
    @Test
    public void testWithMockito() throws IOException, InterruptedException
    {
        QueryCountMapper mapper = new QueryCountMapper();
        Text value = new Text("2011-08-18 18:13:22,781[TAB]캐논 550d[TAB]This is test[TAB]0[TAB]1688"));

        @SuppressWarnings("unchecked")
        Mapper<LongWritable, Text, Text, IntWritable>.Context context = mock(Context.class);
        context.getConfiguration().set(QueryCountMapper.PATTERN, "([^ ]*) ([^ ]*)\\t(.*)\\t(.*)\\t(\\d*)\\t(\\d*)"); // NullPointerException
        context.getConfiguration().set(QueryCountMapper.PATTERN_QUERY, String.valueOf(3));

        mapper.map(null, value, context);

        verify(context, times(2)).write(new Text("캐논 550d"), new IntWritable(1));
    }

    @Test
    public void testWithMRUnit()
    {
        Mapper <LongWritable, Text, Text, IntWritable> mapper = new QueryCountMapper();
        MapDriver <LongWritable, Text, Text, IntWritable> driver = new MapDriver <LongWritable, Text, Text, IntWritable> (mapper);
        driver.getConfiguration().set(QueryCountMapper.PATTERN, "([^ ]*) ([^ ]*)\\t(.*)\\t(.*)\\t(\\d*)\\t(\\d*)");
        driver.getConfiguration().set(QueryCountMapper.PATTERN_QUERY, String.valueOf(3));

        driver.withInput(new LongWritable(1), new Text("2011-08-18 18:13:22,781[TAB]캐논 550d[TAB]This is test[TAB]0[TAB]1688"));
        driver.withOutput(new Text("캐논 550d"), new IntWritable(1));

        driver.runTest();
    }
}

위의 테스트 코드에서 testWithMockito() 메소드에 있는 context.getConfiguration()의 결과가 null이기 때문에 NullPointerException으로 테스트는 실패하게 된다. Context 객체를 생성할 때 Configuration을 세팅해주거나 reflection이라도 이용해서 Configuration을 세팅해 주면 가능할 것 같다. PrivilegedAccessor를 사용해서 Context의 Configuration을 세팅해 볼까 했더니 final 변수라 세팅도 안 된다.

나는 귀찮으니 MRUnit을 사용하기로.. 링크의 글에도 써 있는 것처럼 입력/출력이 명확하고 직관적이라 MRUnit을 사용하는게 더 편할 것 같다. (절대 개인적인 생각)

덧글

댓글 입력 영역

Google AdSense (text/image)