2010-08-25 126 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在希望从队列中删除数据的方法之前,将预期值插入队列中。