Mockito 사용하기 2



 

Mockito 사용하기 1 에서 이어지는 글이다.

@Mock Annotation

Mock 생성은 쓸데없이 반복적이다. @Mock Annotation을 사용하면 좀 더 간단하게 mock을 할 수 있고 코드가독성도 좋아진다. MockitoAnnotations.initMocks() 또는 @RunWith(MockitoJUnitRunner.class)를 사용하면 자동으로 초기화를 해준다.

Iterator-style stubbing

가끔씩 하나의 메소드에서 순차적으로 여러 다른 값을 돌려주거나 예외를 발생시켜야 할 때가 있다. 한 번 stub한 값은 바뀌지 않지만 다음과 같이 매번 호출할 때 마다 다른 행동을 하도록 정할 수 있다.

Stubbing with callbacks

이때까지의 예제에서는 stub 할 때 모두 특정값을 넣었다. 만약 mock의 상태나 메소드 인자값에 따라 다른 값을 돌려주게 하게 만들고 싶다면 어떻게 해야할까. Answer<?> 클래스를 사용하면 가능하다. 하지만 아주 특별한 상황이 아니라면 크게 사용할 일은 없을 듯하다.

이 예제에서는 넘겨 받은 값에다가 1을 더해서 넘겨주도록 했다.

Spying on real objects

spy()는 진짜 인스턴스를 mock하는 것이다. 당연히 spy된 인스턴스를 stub 할 수 있다.

단, 어떤 경우는 stub 할 때 조심해야 한다. 위의 when(spy.get(10))에서는 진짜 인스턴스의 메소드를 호출하기 때문에 IndexOutOfBountException이 발생하게 된다. 이럴 경우 doReturn()를 사용해서 문제를 회피할 수 있다.

Argument Matcher

이전의 예제에서 말했던 anyInt(), anyString()의 커스터마이즈 버전이다. stub, verification 용으로 쓸 수 있다. 클래스를 상속해서 matches()를 직접 구현하면 된다. 여러 곳에 재사용할 일이 경우 사용하면 좋다.

Capturing arguments for further assertions

Argument Matcher와 비슷한 기능을 가지고 있는 Argument Captor라는 것도 있다. Argument Matcher와 다른 점은 따로 클래스를 만들 필요가 없다는 점, 그리고 verification에만 사용할 수 있다는 점이다.

Resetting mocks

mock을 초기화를 위해서는 reset()을 사용하면 된다. 사실 간단히 새로 mock을 하나 만들면 되기 때문에 거의 쓸 일은 없을 것이다.

Verification with timeout

실행시간이 중요한 메소드라면 timeout()을 사용해서 검증할 수 있다. times()atLeast()와도 같이 사용할 수 있다.

One-liner stubs

체이닝(chaining)을 이용해서 mock 생성과 stub 까지 한 줄에 만들 수 있다. 마지막에 getMock()이 중요한 포인트. 코드가독성도 좋은 편이다.

Mocking Details

거의 쓸 일은 없을 것 같지만 mock인지 spy 된 인스턴스인지 확인도 할 수 있는 기능도 지원한다.

이것보다 훨씬 더 많은 기능들이 있으므로 공식 웹사이트의 문서를 보면 도움이 될 것이다. 현재 2.x 버전이 베타테스트 중이므로 나중에는 이 예제가 동작하지 않을 가능성이 있다. 이어지는 글에서는 PowerMock에 대해서 이야기할 것이다.