2014.12.08 16:31

Android unit test 를 작성하면서 retrofit 을 사용하는 서비스가 있어 이를 어떻게 해야 할까를 고민하던중 찾은 방법


Retrofit 에서 비동기로 콜을 하기 위해선 파라미터로 콜백을 넣어주면 되는데 기존에 생각했던 방법으론(when-then) 으론 어떻게 테스트를 해야 할지 의문이었음


방법은 간단하게 when 절 앞에 doAnswer를 넣어주면 됨.



MyApi mock = mock(MyApi.class);


doAnswer(new Answer() {

@Override

public Object answer(InvocationOnMock invocation) throws Throwable {

Object[] args = invocation.getArguments();

Callback<MyData> callback = (Callback<MyData>) args[0];

callback.success(dummy.myData, null);

return null;

}

}).when(mock).fetchMyData(any(Callback.class));


final DoneMarker doneMarker = new DoneMarker();

mock.fetchMyData(new Callback<MyData>() {

@Override

public void success(MyData myData, Response response) {

assertThat(myData, notNullValue());

assertThat(myData, is(dummy.myData));

doneMarker.done();

}


@Override

public void failure(RetrofitError error) {

fail();

doneMarker.done();

}

});


await().atMost(1, SECONDS).until(doneMarker);



Retrofit 으로 만든 Api 인터페이스의 클래스를 mock 으로 만들고, doAnswer-when 순으로 테스트 코드를 위한 준비 작업을 함.


doAnswer절에선 callback 을 호출해주면 되고, 우리가 테스트 하고자 하는 매서드의 파라미터로는 콜백을 넣어주면 되는데, 모든 콜백을 받기로 하겠다면(모든 콜백을 파라미터로 넣으면, 어떤 콜백이든, doAnswer 절에 정의한 answer가 실행됨) any 를 써서 넣어주면 됨.


그리고 콜백이 비동기로 이뤄지기 때문에(위 코드에선 그렇진 않지만) assertion 을 콜백 내부에서 해준다. 그리고 매서드 호출 마지막에 await() 으로 최대 1초간 doneMarker 가 true 를 리턴할 때까지 기다린다.

* await 은 awaitility 라이브러리의 매서드



저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 0


티스토리 툴바