programing

모키토로 보이드 메서드를 조롱하는 방법

prostudy 2022. 6. 21. 22:31
반응형

모키토로 보이드 메서드를 조롱하는 방법

void 리턴 타입의 메서드는 어떻게 모사합니까?

옵저버 패턴을 구현했습니다만, 방법을 모르기 때문에 모키토에서는 조롱할 수 없습니다.

그리고 인터넷에서 예를 찾아보려고 노력했지만 성공하지 못했다.

제 수업은 다음과 같습니다.

public class World {

    List<Listener> listeners;

    void addListener(Listener item) {
        listeners.add(item);
    }

    void doAction(Action goal,Object obj) {
        setState("i received");
        goal.doAction(obj);
        setState("i finished");
    }

    private string state;
    //setter getter state
} 

public class WorldTest implements Listener {

    @Test public void word{
    World  w= mock(World.class);
    w.addListener(this);
    ...
    ...

    }
}

interface Listener {
    void doAction();
}

시스템은 mock을 사용하여 트리거되지 않는다.

상기의 시스템 상태를 나타내고 싶다.그리고 그에 따라 주장을 펴라.

Mockito API 문서를 참조하십시오.링크된 문서에 기재된 바와 같이 (Point # 12)는doThrow(),doAnswer(),doNothing(),doReturn()Mockito 프레임워크에서 모의 보이드 메서드에 이르는 메서드 패밀리.

예를들면,

Mockito.doThrow(new Exception()).when(instance).methodName();

혹은 후속 행동과 결합하고 싶다면

Mockito.doThrow(new Exception()).doNothing().when(instance).methodName();

세터를 조롱하고 있다고 가정하고setState(String s)아래 클래스에서 코드는 다음과 같습니다.doAnswer조롱하는 방법setState.

World mockWorld = mock(World.class); 
doAnswer(new Answer<Void>() {
    public Void answer(InvocationOnMock invocation) {
      Object[] args = invocation.getArguments();
      System.out.println("called with arguments: " + Arrays.toString(args));
      return null;
    }
}).when(mockWorld).setState(anyString());

이 질문에 대한 더 간단한 답을 찾은 것 같습니다. 한 가지 메서드에 대해 실제 메서드를 호출하려면(비록 void return이 있더라도) 다음과 같이 할 수 있습니다.

Mockito.doCallRealMethod().when(<objectInstance>).<method>();
<objectInstance>.<method>();

또는 다음과 같이 해당 클래스의 모든 메서드에 대해 실제 메서드를 호출할 수 있습니다.

<Object> <objectInstance> = mock(<Object>.class, Mockito.CALLS_REAL_METHODS);

@sateesh가 말한 것 외에 테스트 호출을 방지하기 위해 void 메서드를 조롱하고 싶을 때는 void 메서드를 사용할 수 있습니다.Spy이 방법:

World world = new World();
World spy = Mockito.spy(world);
Mockito.doNothing().when(spy).methodToMock();

테스트를 실행하는 경우 테스트에서 메서드를 호출해야 합니다.spy반대하며, 반대하지 않다world물건.예를 들어 다음과 같습니다.

assertEquals(0, spy.methodToTestThatShouldReturnZero());

이른바 문제의 해결 방법은 다음과 같은 방법을 사용하는 것입니다.spy mockito.spy(...) 대신mock Mockito.mock(..)

스파이는 부분적인 조롱을 가능하게 한다.이 일은 모키토가 잘해요.완성되지 않은 수업이 있기 때문에 이 수업에서 필요한 부분을 조롱하는 것입니다.

먼저, 항상 mockito static을 Import해야 합니다.이렇게 하면 코드가 훨씬 읽기 쉽고 직관적입니다.

import static org.mockito.Mockito.*;

부분적인 조롱과 나머지 모키토에 대한 독창적인 기능을 유지하기 위해 "스파이"를 제공합니다.

다음과 같이 사용할 수 있습니다.

private World world = spy(new World());

메서드가 실행되지 않도록 하려면 다음과 같은 방법을 사용할 수 있습니다.

doNothing().when(someObject).someMethod(anyObject());

메서드에 몇 가지 사용자 지정 동작을 부여하려면 "when"과 "then Return"을 함께 사용합니다.

doReturn("something").when(this.world).someMethod(anyObject());

더 많은 예시는 문서에서 우수한 모키토 샘플을 찾아보세요.

mockito를 사용하여 보이드 방법을 조롱하는 방법 - 두 가지 옵션이 있습니다.

  1. doAnswer- 우리가 조롱하는 보이드 방식을 원하는 경우( 보이드 방식에도 불구하고 행동을 모방함).
  2. doThrow또... - - -거...Mockito.doThrow()조롱된 보이드 방식에서 예외를 발생시키고 싶은 경우.

다음은 사용 방법의 예입니다(이상적인 사용 사례는 아니지만 기본적인 사용 방법을 설명하고자 함).

@Test
public void testUpdate() {

    doAnswer(new Answer<Void>() {

        @Override
        public Void answer(InvocationOnMock invocation) throws Throwable {
            Object[] arguments = invocation.getArguments();
            if (arguments != null && arguments.length > 1 && arguments[0] != null && arguments[1] != null) {

                Customer customer = (Customer) arguments[0];
                String email = (String) arguments[1];
                customer.setEmail(email);

            }
            return null;
        }
    }).when(daoMock).updateEmail(any(Customer.class), any(String.class));

    // calling the method under test
    Customer customer = service.changeEmail("old@test.com", "new@test.com");

    //some asserts
    assertThat(customer, is(notNullValue()));
    assertThat(customer.getEmail(), is(equalTo("new@test.com")));

}

@Test(expected = RuntimeException.class)
public void testUpdate_throwsException() {

    doThrow(RuntimeException.class).when(daoMock).updateEmail(any(Customer.class), any(String.class));

    // calling the method under test
    Customer customer = service.changeEmail("old@test.com", "new@test.com");

}
}

Mockito를 사용한 void 메서드의 모의테스트에 대한 자세한 내용은 제 투고 "Mockito를 사용한 모의 방법(예시를 포함한 포괄적인 가이드)"에서 확인할 수 있습니다.

8에서는, Java 8 의 , 「Import」, 「Import」, 「Import」가 것을 전제로 , 더 하게 할 수 .org.mockito.Mockito.doAnswer:

doAnswer(i -> {
  // Do stuff with i.getArguments() here
  return null;
}).when(*mock*).*method*(*methodArguments*);

return null;이 없으면 컴파일은 가 발생합니다.이 컴파일은 수 없기 때문입니다.doAnswer.

를 들어, 「」라고 하는 것은,ExecutorService할 수 있습니다.Runnableexecute()하다

doAnswer(i -> {
  ((Runnable) i.getArguments()[0]).run();
  return null;
}).when(executor).execute(any());

다른 답변을 묶음(말장난 의도 없음)에 추가합니다.

spy를 사용할 수 없는 경우에는 doAnswer 메서드를 호출해야 합니다.단, 반드시 자신의 답변을 롤링할 필요는 없습니다.디폴트 실장은 몇 가지 있습니다.특히 CallsRealMethods 입니다.

실제로는 다음과 같습니다.

doAnswer(new CallsRealMethods()).when(mock)
        .voidMethod(any(SomeParamClass.class));

또는 다음 중 하나를 선택합니다.

doAnswer(Answers.CALLS_REAL_METHODS.get()).when(mock)
        .voidMethod(any(SomeParamClass.class));

나는 너의 문제가 너의 시험 구조 때문이라고 생각해.테스트 클래스의 인터페이스를 실장하는 종래의 방법(여기서와 같이)과 조롱을 조합하는 것은 어려운 일이었습니다.

청취자를 모의로 구현하면 상호 작용을 확인할 수 있습니다.

Listener listener = mock(Listener.class);
w.addListener(listener);
world.doAction(..);
verify(listener).doAction();

이것은 '세계'가 옳은 일을 하고 있다는 것을 만족시킬 것이다.

시뮬레이트된 void 메서드로 작업을 수행해야 하는 경우 void 메서드로 전송된 인수를 조작해야 하는 경우 Mockito.doAnswer와 ArgumentCaptor.capture 메서드를 조합할 수 있습니다.

예를 들어, SomeServiceMethod라고 불리는 비활성 메서드를 가진 갤럭시 서비스를 자동 연결하는 SpaceService가 있다고 가정합니다.

스페이스 서비스에서 갤럭시 서비스의 보이드 메서드를 호출하는 메서드 중 하나에 대한 테스트를 작성하려고 합니다.행성도 Space Service 내에서 생성됩니다.그러니 그걸 비웃을 기회가 전혀 없겠군요.

다음은 테스트를 작성할 샘플 SpaceService 클래스입니다.

class SpaceService {
    @Autowired
    private GalaxyService galaxyService;

    public Date someCoolSpaceServiceMethod() {
        // does something

        Planet planet = new World();
        galaxyService.someServiceMethod(planet); //Planet updated in this method.

        return planet.getCurrentTime();
    }
}

갤럭시 서비스someServiceMethod 메서드는 planet 인수를 요구합니다.그 방법에서 몇 가지 일을 합니다.다음을 참조해 주세요.

GalaxyService {
    public void someServiceMethod(Planet planet) {
        //do fancy stuff here. about solar system etc.

        planet.setTime(someCalculatedTime); // the thing that we want to test.

        // some more stuff.
    }
}

이 기능을 테스트합니다.

다음은 예를 제시하겠습니다.

ArgumentCaptor<World> worldCaptor = ArgumentCaptor.forClass(World.class);
Date testDate = new Date();

Mockito.doAnswer(mocked-> {
    World capturedWorld = worldCaptor.getValue();
    world.updateTime(testDate);
    return null;
}).when(galaxyService.someServiceMethod(worldCaptor.capture());

Date result = spaceService.someCoolSpaceServiceMethod();

assertEquals(result, testDate);

이 예에서는 Listener 항목을 조롱하고 Mockito를 사용해야 합니다.상호 작용을 확인하기 위해 확인

언급URL : https://stackoverflow.com/questions/2276271/how-to-mock-void-methods-with-mockito

반응형