mockitoでモックを無効にする方法

java mocking mockito unit-testing
mockitoでモックを無効にする方法

void戻り値型を使用してメソッドをモックする方法は?

Observerパターンを実装しましたが、方法がわからないため、Mockitoでモックできません。

そして、私はインターネットで例を見つけようとしましたが、成功しませんでした。

私のクラスは

public class World {

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

システムはモックでトリガーされません。 =(上記のシステム状態を表示したい。 そして、彼らに従って主張をしなさい。

  777  155


ベストアンサー

Mockito API docsをご覧ください。 リンクされたドキュメントが言及しているように(ポイント#12)、Mockitoフレームワークのメソッドの doThrow()doAnswer()doNothing()、 `doReturn()`ファミリのいずれかを使用してvoidメソッドをモックできます。

例えば、

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

または、フォローアップ行動と組み合わせたい場合は、

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

以下のWorldクラスのセッター setState(String s)`のモックを見ていると仮定すると、コードは `doAnswer`メソッドを使用して setState`をモックします。

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

993


私はその質問に対するより簡単な答えを見つけたと思う、ただ1つのメソッドのために実際のメソッドを呼び出すために(それがvoidリターンを持っているとしても)あなたはこれを行うことができます:

Mockito.doCallRealMethod().when().();
.();

または、次のようにして、そのクラスのすべてのメソッドに対して実際のメソッドを呼び出すことができます。

  = mock(.class, Mockito.CALLS_REAL_METHODS);

90


@sateeshが言ったことに加えて、テストがそれを呼び出さないようにするためにvoidメソッドをモックしたい場合、この方法で `Spy`を使用できます。

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

テストを実行したいときは、 world`オブジェクトではなく、 spy`オブジェクトでtestのメソッドを呼び出してください。 例えば:

assertEquals(0,spy.methodToTestThatShouldReturnZero());

57


いわゆる問題の解決策は、 spy Mockito.spy(…​ )「モック」の代わりにhttp://mockito.googlecode.com/hg-history/1.5/javadoc/org/mockito/Mockito.html#mock%28java.lang.Class%29 [Mockito.mock(.. )]。

スパイにより、部分的なモックが可能になります。 Mockitoはこの問題に長けています。 完全ではないクラスがあるため、この方法でこのクラスの必要な場所をモックします。

52


まず、mockito staticを常にインポートする必要があります。これにより、コードがはるかに読みやすく(直感的に)なります。

import static org.mockito.Mockito.*;

部分的なモックを行い、残りの部分で元の機能を維持するために、mockitoは「スパイ」を提供します。

次のように使うことができます。

private World world = spy(World.class);

メソッドの実行を排除するには、次のようなものを使用できます。

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

メソッドにカスタム動作を与えるには、「thenReturn」とともに「when」を使用します。

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

その他の例については、ドキュメントでmockitoサンプルを参照してください。

23


  • mockitoでvoidメソッドをモックする方法-2つのオプションがあります*

    1. doAnswer-モックされたvoidメソッドに何かをさせたい場合(モック
      無効であるにもかかわらず動作)。

    2. doThrow-をスローしたい場合は` Mockito.doThrow() `があります
      モック化されたvoidメソッドからの例外。

以下は、その使用方法の例です(理想的なユースケースではありませんが、基本的な使用法を説明したかっただけです)。

@Test
public void testUpdate() {

    doAnswer(new Answer() {

        @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("[email protected]", "[email protected]");

    //some asserts
    assertThat(customer, is(notNullValue()));
    assertThat(customer.getEmail(), is(equalTo("[email protected]")));

}

@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("[email protected]", "[email protected]");

}
}

私の投稿https://javacodehouse.com/mockito-tutorial[Mockitoでモックする方法(例付きの包括的なガイド)]で、Mockitoでメソッドを*モック*および*テスト* * void *する方法の詳細を見つけることができます。

18


束に別の答えを追加します(しゃれはありません)…​

スパイを使用したくない場合は、doAnswerメソッドを呼び出す必要があります。 ただし、必ずしも独自のhttp://docs.mockito.googlecode.com/hg/org/mockito/stubbing/Answer.html[Answer]を実行する必要はありません。 いくつかのデフォルトの実装があります。 特に、http://docs.mockito.googlecode.com/hg/org/mockito/internal/stubbing/answers/CallsRealMethods.html [CallsRealMethods]。

実際には、次のようになります。

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

Or:

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

13


Java 8では、 `org.mockito.Mockito.doAnswer`の静的インポートがあると仮定すると、これを少し簡潔にすることができます。

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

「return null;」は重要です。それがないと、「doAnswer」の適切なオーバーライドを見つけることができないため、コンパイルはかなり不明瞭なエラーで失敗します。

たとえば、「execute()」に渡された「Runnable」をすぐに実行する「ExecutorService」は、次を使用して実装できます。

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

6


問題はテスト構造に起因すると思います。 ここでやったように、モックとテストクラスでインターフェイスを実装する従来の方法を混在させるのは難しいことがわかりました。

リスナーをモックとして実装すると、相互作用を検証できます。

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

これは、「世界」が正しいことをしていることを満足させるはずです。

5


__
@アシュリー:私のために働く

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

__

0


タイトルとURLをコピーしました