2010-08-25 128 views
6

如何使用EasyMock修改模擬方法的可變方法參數?EasyMock和修改可變方法參數

例如,我有一個使用BlockingQueue的類。我想模擬BlockingQueue成員進行單元測試。我的類調用方法queue.drainTo(Collection c)。調用此方法將從隊列中移除元素並將其添加到集合中。我將如何使用EasyMock模擬這種行爲?例子會很棒。

回答

0

很難說清楚你的代碼是什麼樣的。可以幫助你更好的,如果我知道你要測試的代碼..但假設你想測試你的代碼如下所示:

private BlockingQueue<String> queue; 
private List<String> myList = new ArrayList<String>(): 

private void setBlockingQueue(BlockingQueue<String> queue) { 
    this.queue = queue; 
} 

public List<String> getMyList() { 
    return myList; 
} 

public void setMyList(List<String> myList) { 
    this.myList = myList; 
} 

public void doWork() { 
    System.out.println("blah"); 
    queue.drainTo(myList); 
} 

測試將

public void testDoWork() { 
    List<String> stuffToDrain = new ArrayList<String>(); 
    stuffToDrain.add("foo"); 
    stuffToDrain.add("bar"); 
    myTestingClass.setMyList(stuffToTrain); 


    BlockingQueue<String> queue = EasyMock.createMock(BlockingQueue.class ); 
    myTestingClass.setBlockingQueue(queue); 
    queue.drainTo(stuffToDrain); 
    EasyMock.replay(queue); 
    myTestingClass.doWork(); 
    EasyMock.verify(queue); 



} 

很抱歉,如果這ISN」但是真的很難建議測試代碼,我看不到...

編輯 - 我們不能真正斷言,可變的參數被改變,因爲我們如何使用模擬。我們所能做的就是斷言drainTo方法被調用。如果drainTo做我們想做的事情將不得不在其他地方進行測試..即在BlockingQueue.class

的測試中編輯2 - 我們可以更具體地說明我們希望調用方法的列表。

+0

對不起,沒有發佈任何代碼,但你的'myTestingClass'幾乎釘我以後。我正在查看你的測試代碼。通過運行此測試,stuffToDrain列表如何被添加到myList中? – 2010-08-25 19:40:37

+0

它不會被添加到列表中。你不能在這裏測試。您將需要測試,在一個單獨的測試。(或因爲BlockingQueue的就是Java的一部分,你只是認爲它是正確的,沒有測試它) – bwawok 2010-08-25 19:42:13

+0

OK, 有沒有什麼辦法讓EasyMock的修改可變參數? – 2010-08-25 19:44:39

12

您可以使用andAnswergetCurrentArguments

public void testDrainToQueue() { 
    BlockingQueue<Foo> queue = EasyMock.createMock(BlockingQueue.class); 
    EasyMock.expect(queue.drainTo(EasyMock.isA(List.class))) 
     .andAnswer(new IAnswer<Integer>() { 
     public Integer answer() { 
      ((List) EasyMock.getCurrentArguments()[0]).add(new Foo(123)); 
      return 1; // 1 element drained 
     } 
     }); 
    EasyMock.replay(queue); 
    ... 
} 

它有時幫助提取一個輔助類或方法:

private static IAnswer<Integer> fakeDrainReturning(final List drainedElements) { 
    return new IAnswer<Integer() { 
    @Override public Integer answer() { 
     ((List) EasyMock.getCurrentArguments()[0]).addAll(drainedElements); 
     return drainedElements.size(); 
    } 
    }; 
} 

然後,你可以這樣做:

List<Foo> drainedElements = Arrays.asList(new Foo(123), new Foo(42)); 
EasyMock.expect(queue.drainTo(EasyMock.isA(List.class))) 
    .andAnswer(fakeDrainReturning(drainedElements)); 

它可能更好地使用真實的BlockingQueue並找到一種方法來插入th在希望從隊列中刪除數據的方法之前,將預期值插入隊列中。