6

私のアプリケーションでは、一部の操作にオブザーバー パターンを使用しており、それらを単体テストでテストしたいと考えています。問題は、junit/mockito/他の何かを使用してオブザーバーをテストする方法がわからないことです。何か助けはありますか?

たとえば、これは私の単体テストです:

@Before
public void setUp() throws IOException, Exception {
    observer = new GameInstanceObserver(); // observable (GameInstance) will call update() method after every change
    GameInstance.getInstance().addObserver(observer); // this is observable which is updated by serverService
}

@Test(expected = UserDataDoesntExistException.class)
public void getRoomUserData_usingNullKey_shouldThrowUserDataDoesntExist() throws InterruptedException, UserDataDoesntExistException {
    serverService.createRoom("exampleRoom"); // this operation is asynchronous and updates GameInstance data (as I wrote before GameInstance is Observable)
    Thread.sleep(400); // how to do it in better way?

    GameInstance gi = (GameInstance) observer.getObservable();
    assertTrue(gi.getRoom("exampleRoom").getRoomId().equals("exampleRoom"));
}

私はThread.sleep()それをそのように(または同様の方法で)使用したり使用したりしたくありません:

@Test(expected = UserDataDoesntExistException.class)
public void getRoomUserData_usingNullKey_shouldThrowUserDataDoesntExist() throws InterruptedException, UserDataDoesntExistException {
    serverService.createRoom("exampleRoom"); // this operation is asynchronous and updates GameInstance data (as I wrote before GameInstance is Observable)
    waitUntilDataChange(GameInstance.getInstance()); // wait until observable will be changed so I know that it notified all observer and I can validate data

    GameInstance gi = (GameInstance) observer.getObservable();
    assertTrue(gi.getRoom("exampleRoom").getRoomId().equals("exampleRoom"));
}
4

1 に答える 1

9

私の理解が正しければ、問題は実際にはオブザーバーをテストすることではなく、非同期メソッド呼び出しの結果をテストすることです。そのためには、update() メソッドが呼び出されるまでブロックするオブザーバーを作成します。次のようなもの:

public class BlockingGameObserver extends GameInstanceObserver {
    private CountDownLatch latch = new CountDownLatch(1);

    @Override
    public void update() {
        latch.countDown();
    }

    public void waitUntilUpdateIsCalled() throws InterruptedException {
        latch.await();
    }
}

そしてあなたのテストで:

private BlockingGameObserver observer;

@Before
public void setUp() throws IOException, Exception {
    observer = new BlockingGameObserver();
    GameInstance.getInstance().addObserver(observer); 
}

@Test
public void getRoomUserData_usingNullKey_shouldThrowUserDataDoesntExist() throws InterruptedException, UserDataDoesntExistException {
    serverService.createRoom("exampleRoom");   
    observer.waitUntilUpdateIsCalled();
    assertEquals("exampleRoom",
                 GameInstance.getInstance().getRoom("exampleRoom").getRoomId());
}
于 2013-05-19T16:42:36.257 に答える