2013-10-19 7 views
1

Mockito를 사용하여 몇 가지 사항을 확인하고 싶습니다. 설명서를 읽으면 일반적인 Mockito 도구를 벗어나지 않으면 불가능하다고 생각합니다.Mockito에 대한 맞춤 VerificationMode 클래스 만들기

DrawTool tool = mock(DrawTool.class); 
new Drawer().draw(tool); 
verify(tool).begin(); // Make sure begin and end are called exactly once each 
verify(tool).end(); 
InOrder inOrder = inOrder(tool); 
inOrder.verify(tool).begin(); 
inOrder.verify(tool).end(); 
inOrder.verify(tool).flush(); 
inOrder.verifyNoMoreInteractions(); 

이 테스트는 flush가 마지막 상호 작용임을 확인뿐만 아니라 몇 가지를 확인하지만, Mockito가 begin 첫 번째 상호 작용인지 확인 할 수있는 방법이없는 것 같다 : 예는이 걸릴. 나는 Mockito의 툴에서의 비대칭성에 놀라기 때문에 사용자 정의 VerificationMode를 만들 가능성을 조사하고 있습니다. 나는 뭔가라는 beforeAnyOther 같은 VerificationMode를 작성하고 다음과 같이 사용하고 싶습니다 :

inOrder.verify(tool, beforeAnyOther()).begin(); 
inOrder.verify(tool).end(); 
inOrder.verify(tool, beforeAnyOther()).flush(); 
inOrder.verifyNoMoreInteractions(); 

의도가 begin가 떠나있는 동안 endflush 사이에 관련 상호 작용이 없는지 먼저 호출되고 있는지 확인하는 것입니다 beginend 사이의 상호 작용이 없습니다.

나는 기존의 VerificationMode에 대한 소스 코드를 연구 해왔다. 원칙적으로 이것은 구현할 간단한 VerificationMode가되어야하지만 일단 Mockito의 주요 클래스를 넘어 서면 문서가 매우 얇아지고 나는이 수업을 만지지 말아야한다고 말해 주려고합니다. 특히 org.mockito.internal을 시작하는 패키지는주의해야합니다. 왜냐하면 그 이름은 공개 되어도이 클래스가 변경 될 수 있음을 나에게 알리기 때문입니다.

VerificationMode 구현을위한 매우 중요한 클래스는 모두 org.mockito.internal.verification.api 패키지에있는 것 같습니다. 전체 패키지에는 javadoc이 1 비트 밖에없는 것 같으며, "이 패키지는 확인 API가 완전히 완성되면 공개됩니다." 이 패키지가 적극적으로 수정되고 있으므로 패키지에 포함 된 내용을 사용해서는 안되며 실제로 수년 동안 말했던 패키지와 패키지가 실제로 변경되지 않을 것입니다.

org.mockito.internal.verification.api 클래스를 사용할 수없는 경우 사용자 지정 VerificationModes를 구현할 수없는 것 같습니다. 사용자 정의 VerificationMode없이 이와 같은 작업을 수행 할 수있는 방법이 있습니까?

+2

[Mockito 사용자 그룹] (https://groups.google.com/forum/#!forum/mockito)에 게시 할 가치가 있습니다. – Jonathan

답변

2

모의에서 발생할 호출 순서를 완전히 지정할 수 있다면 beforeAnyOther 확인 모드가 필요하지 않습니다. 예를 들어,

  • flush가 다른 통화 tool
  • 에 이루어지지 한 번
  • 을 호출되는 다음,
  • end 번 호출되는 후,
    • begin

      한 번 호출됩니다 ... 원하는 행동이 가정

    다음 작업을 수행해야합니다.

    // Verify that the three invocations arrived in the desired order. 
    InOrder inOrder = inOrder(tool); 
    inOrder.verify(tool).begin(); 
    inOrder.verify(tool).end(); 
    inOrder.verify(tool).flush(); 
    
    // Verify that the three invocations are all we received. 
    Mockito.verify(tool).begin(); 
    Mockito.verify(tool).end(); 
    Mockito.verify(tool).flush(); 
    Mockito.verifyNoMoreInteractions(); 
    

    한편, 확인하려는 시퀀스 외부에서 추가 호출이 발생하면 올바른지, Mockito는 현재이를 확인할 수 없습니다. 따라서 예를 들어, 사이의 어떤 지점에서 tool.setPenColor()에 전화해야한다는 것을 알았다면 end으로 전화하기 전이나 후에 전화가 오는지는 중요하지 않습니다. 운이 좋지 않을 수 있습니다.

    다른 조롱 라이브러리에서이 상황을 처리 할 수 ​​있습니다. 다루기 힘든 경우,

    DrawTool mock = EasyMock.createMock(DrawTool.class); 
    EasyMock.checkOrder(mock, true); 
    mock.begin(); 
    EasyMock.expectLastCall(); 
    EasyMock.checkOrder(mock, false); 
    mock.end(); 
    EasyMock.expectLastCall(); 
    EasyMock.expect(mock.someOtherCallThatReturnsAValue()).andReturn(null); 
    EasyMock.checkOrder(mock, true); 
    mock.flush(); 
    EasyMock.expectLastCall(); 
    EasyMock.replay(mock); 
    
    new Drawer().draw(tool); 
    
    EasyMock.verify(mock); 
    

    동등한 테스트가 가능한 것으로 나타납니다 flush 마지막 온다, 우리는 중간에 전화에 대한 상관 없어, begin 먼저 오는 순서를 위해, 예를 들어 - EasyMock에이 쉬운 만든다 JMock 1에서는 biteasier이지만이 라이브러리는 오래된 것입니다 (JDK 1.3). 따라서 사용하지 마십시오. 이것은 Moxie에서는 불가능합니다 (면책 조항/뻔뻔한 플러그 : 저는 저자입니다). 그러나 이제는 todo list item이 있습니다.

    왜 Mockito 검증 API 문서가 그런 식으로되어 있는지 Mockito 개발자에게 말할 수 없습니다. 메일 링리스트에서 요청하는 것이 가장 좋습니다. 그들이 패치를 환영 할 것이라고 확신합니다.