Programing

모키토의 주장Captor의 예

c10106 2022. 5. 21. 08:30
반응형

모키토의 주장Captor의 예

누가 나에게 사용법을 보여주는 예를 들어줄 수 있니?org.mockito.ArgumentCaptor클래스와 모키토를 제공하는 단순한 행렬과는 어떻게 다른가.

나는 제공된 모키토 문서를 읽었지만, 그 문서들은 그것을 명확하게 설명하지 못하고, 그들 중 누구도 그것을 명확하게 설명할 수 없다.

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

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

이제 내부 데이터를 확인하려면 캡처를 사용하십시오.

// 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);

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

  • 단 하나의 주장이라도 포착하면, 이 주장에 대해 훨씬 더 정교한 테스트를 할 수 있고, 보다 명확한 코드를 가지고 있다.
  • a의ArgumentCaptor두 번 이상 포획할 수 있다.

후자를 설명하려면 다음과 같이 하십시오.

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

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

그러면 캡쳐자가 4개의 모든 인수에 대한 접근 권한을 부여할 수 있을 것이고, 그러면 당신은 별도로 주장을 수행할 수 있다.

다음과 같은 이유로 이 또는 실제로 많은 수의 인수가VerificationMode일정한 수의 호출에만 국한되지 않는다. 어떤 경우에도 캡쳐자가 원하는 경우 모든 호출에 대한 액세스 권한을 부여할 것이다.

이것은 또한 그러한 시험이 당신 자신의 시험을 시행해야 하는 것보다 훨씬 쓰기 쉽다는 이점도 있다.ArgumentMatchers - 특히 모키토를 단언과 결합할 경우.

아, 그리고 JUnit 대신 TestNG를 사용하는 것도 고려해줘.

전체 점검을 위한 단계는 다음과 같다.

먼저 인수 캡터를 준비하십시오.

ArgumentCaptor<ArgumentClass> argumentCaptor = ArgumentCaptor.forClass(ArgumentClass.class);

둘째, 부품에 종속된 부품(시험 대상의 공동작업자)에 대한 호출을 확인하십시오.

시간(1)이 기본값이므로 추가해야 한다.

verify(dependentOnComponent, times(1)).method(argumentCaptor.capture());

셋째, 캡터의 getValue()를 사용하여 인수를 공동작업자에게 전달하십시오.

ArgumentClass someArgument = messageCaptor.getValue();

넷째, 주장을 위해 몇 가지 주장을 사용한다.

나는 저장소를 사용하여 String(종속성 주입 없이, 엔티티 없이)을 저장하는 매우 간단한 서비스를 시뮬레이션하는 이 예를 단지 신속하게 IndistCaptor를 가르치기 위해 만들었다.

  • 서비스는 수신하고 대문자로 변환하여 이름을 자른 다음 저장소를 호출한다.
  • 저장소는 스트링을 "저장"한다.
  • IndressCaptor를 사용하여 리포지토리에 전달되는 값을 확인한 다음 예상대로 잘라내거나 대문자로 표시되는지 확인하십시오.

3개 클래스:PersonService, PersonRepository 및 PersonServiceTest(패키지 생략)

public class PersonService {

    private PersonRepository personRepository;

    public void setPersonRepository(final PersonRepository personRepository) {
        this.personRepository = personRepository;
    }

    public void savePerson(final String name) {
        this.personRepository.save(name.toUpperCase().trim());
    }

}

public class PersonRepository {

    public void save(final String person) {
        System.out.println(".. saving person ..");
    }
}


import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;

class PersonServiceTest {

    @Test
    void testPersonService() {

        // Create the repository mock
        final PersonRepository personRepositoryMock = mock(PersonRepository.class);

        // Create the service and set the repository mock
        final PersonService personService = new PersonService();
        personService.setPersonRepository(personRepositoryMock);

        // Save a person
        personService.savePerson("Mario ");

        // Prepare an ArgumentCaptor to capture the value passed to repo.saveMethod
        final ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);

        // Capture the argument passed in the unique method invocation
        verify(personRepositoryMock, times(1)).save(captor.capture());

        // Check if the captured value is the expected one
        final String capturedParameter = captor.getValue();
        assertEquals("MARIO", capturedParameter);
    }
}

여기서 나는 너에게 콜백 방법의 적절한 예를 제시한다. 그러므로 우리가 메서드 로그인()과 같은 방법을 가지고 있다고 가정하자:

 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 class를 보다 명확히 하기 위해 모든 도우미 클래스를 여기에 배치했다.

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();

}

이제 클래스 로그인의 메서드 로그인()을 테스트하고 싶다.

 @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)

참조URL: https://stackoverflow.com/questions/36253040/example-of-mockitos-argumentcaptor

반응형