Mockito의 argumentCaptor의 예 점 을 보여주는

누구든지 org.mockito.ArgumentCaptor수업 사용 방법 과 mockito와 함께 제공되는 간단한 매처 와 다른 점 을 보여주는 예를 제공해 주 시겠습니까?

제공된 mockito 문서를 읽었지만 그 내용을 명확하게 설명하지는 못하며 명확하게 설명 할 수는 없습니다.



답변

@fge가 말한 것에 더 동의합니다. 예를 보자. 방법이 있다고 생각하십시오.

class A {
    public void foo(OtherClass other) {
        SomeData data = new SomeData("Some inner data");
        other.doSomething(data);
    }
}

내부 데이터를 확인하려면 captor를 사용할 수 있습니다.

// Create a mock of the OtherClass
OtherClass other = mock(OtherClass.class);

// Run the foo method with the mock
new A().foo(other);

// Capture the argument of the doSomething function
ArgumentCaptor<SomeData> captor = ArgumentCaptor.forClass(SomeData.class);
verify(other, times(1)).doSomething(captor.capture());

// Assert the argument
SomeData actual = captor.getValue();
assertEquals("Some inner data", actual.innerData);


답변

두 가지 주요 차이점은 다음과 같습니다.

  • 단일 인수조차도 포착하면이 인수에 대해보다 명확한 테스트를 통해보다 명확한 코드를 작성할 수 있습니다.
  • ArgumentCaptor캡처 할 수 있습니다 번 이상.

후자를 설명하기 위해 다음과 같이 말합니다.

final ArgumentCaptor<Foo> captor = ArgumentCaptor.forClass(Foo.class);

verify(x, times(4)).someMethod(captor.capture()); // for instance

그러면 캡터는 4 개의 모든 인수에 대한 액세스 권한을 부여 할 수 있으며이를 통해 개별적으로 어설 션을 수행 할 수 있습니다.

a 또는 VerificationMode고정 된 수의 호출에 국한되지 않기 때문에,이 또는 임의의 수의 인수 ; 어쨌든, 캡터는 원한다면 그들 모두에게 접근 권한을 부여 할 것입니다.

이것은 또한 자신 ArgumentMatcher의 구현을 수행하는 것보다, 특히 mockito와 assertj를 결합하는 경우 보다 그러한 테스트를 작성하는 것이 훨씬 쉽다는 이점이 있습니다 .

아, JUnit 대신 TestNG 사용을 고려하십시오.


답변

전체 확인을위한 단계는 다음과 같습니다.

체포 자 준비 :

ArgumentCaptor<SomeArgumentClass> someArgumentCaptor = ArgumentCaptor.forClass(SomeArgumentClass.class);

컴포넌트 (테스트중인 주제의 협력자) times (1)에 종속되는 호출이 기본값인지 확인하십시오. 따라서 추가해야합니다.

verify(dependentOnComponent, times(1)).send(someArgumentCaptor.capture());

공동 작업자에게 전달 된 인수 가져 오기

SomeArgumentClass someArgument = messageCaptor.getValue();

어설 션에는 someArgument를 사용할 수 있습니다.


답변

여기서는 하나의 콜백 메소드에 대한 적절한 예를 제공합니다. 따라서 login () 메소드와 같은 메소드가 있다고 가정하십시오.

 public void login() {
    loginService = new LoginService();
    loginService.login(loginProvider, new LoginListener() {
        @Override
        public void onLoginSuccess() {
            loginService.getresult(true);
        }

        @Override
        public void onLoginFaliure() {
            loginService.getresult(false);

        }
    });
    System.out.print("@@##### get called");
}

또한 예제를보다 명확하게하기 위해 모든 도우미 클래스를 여기에 넣습니다. loginService 클래스

public class LoginService implements Login.getresult{
public void login(LoginProvider loginProvider,LoginListener callback){

    String username  = loginProvider.getUsername();
    String pwd  = loginProvider.getPassword();
    if(username != null && pwd != null){
        callback.onLoginSuccess();
    }else{
        callback.onLoginFaliure();
    }

}

@Override
public void getresult(boolean value) {
    System.out.print("login success"+value);
}}

리스너 LoginListener는 다음과 같습니다.

interface LoginListener {
void onLoginSuccess();

void onLoginFaliure();

}

이제 방금 Login 클래스의 login () 메소드를 테스트하고 싶었습니다.

 @Test
public void loginTest() throws Exception {
    LoginService service = mock(LoginService.class);
    LoginProvider provider = mock(LoginProvider.class);
    whenNew(LoginProvider.class).withNoArguments().thenReturn(provider);
    whenNew(LoginService.class).withNoArguments().thenReturn(service);
    when(provider.getPassword()).thenReturn("pwd");
    when(provider.getUsername()).thenReturn("username");
    login.getLoginDetail("username","password");

    verify(provider).setPassword("password");
    verify(provider).setUsername("username");

    verify(service).login(eq(provider),captor.capture());

    LoginListener listener = captor.getValue();

    listener.onLoginSuccess();

    verify(service).getresult(true);

또한 테스트 클래스 위에 주석을 추가하는 것을 잊지 마십시오.

@RunWith(PowerMockRunner.class)
@PrepareForTest(Login.class)


답변