2013-05-19 25 views
4

在我的應用程序中,我使用observer模式進行某些操作,我想在單元測試中對它們進行測試。問題是我不知道如何使用junit/mockito /別的東西來測試觀察者。任何幫助?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")); 
} 

回答

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

謝謝!有用! – pepuch

+1

僅供參考,在GitHub中有一個CountDownLatchAnswer被設計用於此目的:https://github.com/dancerjohn/LibEx/blob/master/testlibex/src/main/java/org/libex/test/mockito/answer /CountDownLatchAnswer.java –

+0

@JohnB,謝謝。我在哪裏可以閱讀關於這個LibEx庫的更多信息?如何使用它,它創建了什麼等等? – pepuch