[java] mockito를 사용하여 void 메소드에 모의 만드는 법


Answers

그 질문에 대한 간단한 대답을 찾았습니다. 단 하나의 메서드에 대한 실제 메서드를 호출하는 것입니다 (void 반환이있는 경우에도)이 작업을 수행 할 수 있습니다.

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

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

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

무효 반환 형식으로 메서드를 조롱하는 방법?

Observer 패턴을 구현했지만 어떻게해야할지 모르기 때문에 Mockito와 조롱 할 수는 없습니다.

인터넷에서 예제를 찾으려고했지만 성공하지 못했습니다.

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

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

시스템은 모의로 실행되지 않습니다. = (위에서 언급 한 시스템 상태를 보여주고 싶습니다.




void 메소드를 mockito로 조롱하는 방법 - 두 가지 옵션이 있습니다.

  1. doAnswer - 우리가 조롱 한 void 메소드가 무언가를하기를 원한다면 (무효 임에도 불구하고 행동을 조롱하십시오).
  2. doThrow - 그런 다음 조롱 된 void 메서드에서 예외를 throw하려면 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 와 모방하는 법 (예제를 포함한 포괄적 인 가이드)




@ashley : 나를 위해 일한다.

public class AssetChangeListenerImpl extends
AbstractAssetChangeListener implements AssetChangeListener {

  @Override
  public void onChangeEvent(final EventMessage message) throws EventHubClientException {
      execute(message);
    }
  }
}

public class AbstractAssetChangeListener {
  protected  void execute( final EventMessage message ) throws EventHubClientException {
    executor.execute( new PublishTask(getClient(), message) );
} } @RunWith(MockitoJUnitRunner.class) public class AssetChangeListenerTest extends AbstractAssetChangeListenerTest {

 public void testExecute() throws EventHubClientException {
    EventMessage message = createEventMesage(EventType.CREATE);
    assetChangeListener.execute(message);
    verify(assetChangeListener, times(1)).execute(message);
} }



소위 문제의 해결책은 mock Mockito.mock(..) 대신에 spy Mockito.spy(...) 를 사용하는 것입니다.

간첩은 부분적 조롱을 가능하게합니다. Mockito는이 문제에 능숙합니다. 여러분은 완전하지 않은 클래스를 가지고 있기 때문에 이런 식으로이 클래스에서 필요한 장소를 조롱합니다.




귀하의 문제는 귀하의 테스트 구조 때문이라고 생각합니다. 필자는 테스트 클래스에서 인터페이스를 구현하는 기존 방법과 조롱을 혼합하는 것이 어렵다는 것을 알았다.

리스너를 Mock으로 구현하면 상호 작용을 확인할 수 있습니다.

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

이것은 '세계'가 옳은 일을하고 있다는 것을 당신을 만족시켜야합니다.




Related