2017-02-02 1 views
0

Mockito를 사용하여 "int"유형의 인수를 캡처하려고합니다. 원시 형에 대한 Mockito ArgumentCaptor를 작성하는 방법은 무엇입니까?

내가 테스트 해요 코드 :

public class Client { 

    private final Board board; 
    private final Server server; 

    private void makeMove() { 
    nextMove = 11; 
    server.nextMove(nextMove); 
    } 

    public void moveAccepted(boolean accepted) { 
    if (accepted) { 
     board.updateBoard(nextMove); 
    } else { 
     ... 
    } 
    } 
} 

그리고 이것은 테스트 코드입니다 :

@RunWith(MockitoJUnitRunner.class) 
public class ClientTest { 

    private Client client; 

    @Mock 
    private Board mockBoard; 

    @Mock 
    private Server mockServer; 

    @Captor 
    private ArgumentCaptor<Integer> moveCaptor; 

    @Test 
    public void testGamePlay() { 
    client.forceNextMove(); 
    verify(mockServer).nextMove(moveCaptor.capture()); // NPE here 
    client.moveAccepted(true); 
    verify(mockBoard).updateBoard(eq(moveCaptor.getValue())); 
    } 
} 

하려고 내가 시험에 NullPointerException이 받고 있어요 결과, 캡처 값은 으로 전달됩니다. server.nextMove 호출.

캡쳐가 null인지 이미 확인했습니다. server.nextMove에 대한 인수 유형을 int에서 정수로 변경하면 정수 모두 올바르게 작동합니다.

"IntArgumentCaptor"와 같은 것을 만들 수있는 방법을 찾지 못했습니다 (matcher 용 anyInt).

server.nextMove없이이 테스트 작업을 수행하는 방법은 있습니까 정수?

답변

2

사용중인 Mockito 버전은 무엇입니까? ArgumentCaptor's implementation에 따르면 다르게 수행 할 필요가 없습니다. 예를 들어 ArgumentCaptor는 forClass (반환 할 기본 유형을 파악할 수 있어야 함) 또는 @Captor (필드 유형을 읽고 forClass을 적절하게 호출 할 수 있음)을 통해 작성되어야하기 때문에 any()을 호출하는 것보다 더 똑똑합니다. Primitives.defaultValue에서

public T capture() { 
    Mockito.argThat(capturingMatcher); 
    return defaultValue(clazz); 
} 

:

/** 
* Returns the boxed default value for a primitive or a primitive wrapper. 
* 
* @param primitiveOrWrapperType The type to lookup the default value 
* @return The boxed default values as defined in Java Language Specification, 
*   <code>null</code> if the type is neither a primitive nor a wrapper 
*/ 
public static <T> T defaultValue(Class<T> primitiveOrWrapperType) { 
    return (T) PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.get(primitiveOrWrapperType); 
} 

당신의 NPE는 제어 코드에서 오는 경우, 그 중요한 기호 : 그것은 Mockito는 verify에 통화 중에 구현에하는 수 연기되어 있음을 나타냅니다 Server.nextMove이 잠금 해제 상태임을 나타냅니다. 이는 Server이 final이거나 Server.nextMove이 final이거나 위의 항목 중 하나가 protected 또는 package-private 인 경우입니다 (Mockito의 일부 버전은 Java 컴파일러가 이러한 작업을 수행하는 합성 방법에 문제가 있음).

ArgumentCaptor.capture()null 인 경우 (위의 코드와 달리) 표시하지 않으면 Mockito 버그처럼 들릴 수 있습니다.

+0

Mockito 문제인 것처럼 보입니다. 나는 1.8.4에서 2.7.1로 업데이트되었고 지금은 문제가 없어졌다. 감사! – MarZ

+0

@MarZ 듣기 좋다! 흥미롭게도 ArgumentCaptor는 1.8.4에서 타입에 맞는 "HandyReturnValues"논리를 가지고있는 것 같습니다 (http://grepcode.com/file/repo1.maven.org/maven2/org.mockito/mockito-core/1.8.4). /org/mockito/ArgumentCaptor.java?av=f), 업그레이드가 무엇인지 잘 모릅니다. 그러나 기뻤습니다. –

관련 문제