1

インターフェースがあります:

interface IEventListener
{
  void onEvent(List <IEvent> events);
}

イベントクラスがあります:

class EventB
{
  private final int id;
  private final A a;
  private final String somethingElse;
...
// constructors, getters
...
}

そして、テストするクラスがあります:

class Doer
{
 IEventListener eventListener;
 void doSomething(Aaa a)
 {
   eventListener.onEvent(Arrays.asList(new EventA(1), new EventC(2)));
...
   eventListener.onEvent(Arrays.asList(new EventB(42, a.getA(), "foo"), new EventA(3), new EventB(0, a.getA(), "bar")));
...
   eventListener.onEvent(Arrays.asList(new EventC(4)));
 }
}

これDoerはテストする必要があるコードであり、メソッドdoSomethingは一連のイベントを生成します。特定の条件で特定のイベントを生成するかどうかをテストする必要があります。

より正確には、メソッドを呼び出し、doSomethingEventB が「42」で送信Aされ、メソッド引数から送信されることを確認する単体テストが必要ですa。他のすべてのイベントは無視する必要があります。

このようなテストを行うために、ArgumentCaptor、for-blocks、および魔法のブールフラグを使用した非常に冗長なコードを含むソリューションしか思いつきませんでした...

単体テストを作成する最良の方法は何ですか? コード設計が悪いのでしょうか?

4

3 に答える 3

2

設計は正しいです。Mockito でテストする方法は次のとおりです。

import org.hamcrest.Matchers;
import org.mockito.Mockito;
public void firesEventsOnDoSomething() {
  Listener listener = Mockito.mock(Listener.class);
  Doer doer = new Doer(listener);
  doer.doSomething(aaa);
  Mockito.verify(listener).onEvent(
    Mockito.argThat(
      Matchers.hasItem(
        Matchers.allOf(
          Matchers.instanceOf(EventB.class),
          Matchers.hasProperty("a", Matchers.equalTo(aaa.getA())),
          // whatever you want
        )
      )
    )
  );
}

Mockito 1.9.0 と Hamcrest-library 1.2.1 です。

JUnit 4.10 を Hamcrest-library 1.2.1 と一緒に使用するには、artifact を使用し、そこからjunit:junit-dep:4.10除外する必要があります。org.hamcrest:hamcrest-core

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit-dep</artifactId>
  <version>4.10</version>
  <scope>test</scope>
  <exclusions>
    <exclusion>
      <groupId>org.hamcrest</groupId>
      <artifactId>hamcrest-core</artifactId>
    </exclusion>
  </exclusions>
</dependency>
<dependency>
  <groupId>org.hamcrest</groupId>
  <artifactId>hamcrest-core</artifactId>
  <version>1.2.1</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.hamcrest</groupId>
  <artifactId>hamcrest-library</artifactId>
  <version>1.2.1</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.mockito</groupId>
  <artifactId>mockito-core</artifactId>
  <version>1.9.0</version>
  <scope>test</scope>
  <exclusions>
    <exclusion>
      <groupId>org.hamcrest</groupId>
      <artifactId>hamcrest-core</artifactId>
    </exclusion>
  </exclusions>
</dependency>
于 2012-05-14T16:15:51.547 に答える
0

のダミー実装を作成EventListener:

class DummyEventListener implements EventListener {
    private int expectedId;
    DummyEventListener(int expectedId) {
       this.expectedId = expectedId;
    }
    void onEvent(List <IEvent> events) {
        for (IEvent event : events) {
            if (!(event instanceof EventB)) {
                continue;
            }
            EventB eb = (EventB)event;
            assertEquals(expectedId, eb.getId());
            // add more asserts here
        }
    }
}

あるいは、EasyMock、JMock、Mockito、JMockit などの利用可能な Java モックアップ フレームワークのいずれかを使用できます。

于 2012-05-14T15:45:20.330 に答える
0

JUnit4 を使用している場合は、パラメーター化されたテストを試すことができます。ここにhttp://www.mkyong.com/unittest/junit-4-tutorial-6-parameterized-test/の例があります。

パラメータごとに異なる結果と比較する必要がある場合は、それらを異なるテストケースとして検討することをお勧めします。

于 2012-05-14T15:39:45.030 に答える