EasyMock 和修改可变方法参数

发布于 2024-09-16 04:04:28 字数 187 浏览 9 评论 0原文

如何使用 EasyMock 修改模拟方法的可变方法参数?

例如,我有一个使用 BlockingQueue 的类。我想模拟 BlockingQueue 成员进行单元测试。我的类调用方法queue.drainTo(Collection c)。调用此方法将从队列中删除元素并将它们添加到集合中。我如何使用 EasyMock 模拟这种行为?例子会很棒。

How does one use EasyMock to modify a mocked method's mutable method parameter?

For example, I have class that uses a BlockingQueue. I want to mock the BlockingQueue member for unit testing. My class calls the method queue.drainTo(Collection c). Calling this method removes elements from the queue and adds them to the collection. How would I mock this behavior using EasyMock? Examples would be great.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蓦然回首 2024-09-23 04:04:28

您可以使用 andAnswer 和 getCurrentArguments

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 并找到一种方法,在您希望删除的方法之前将所需的值插入队列中来自队列的数据。

You can use andAnswer and getCurrentArguments:

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);
  ...
}

It sometimes helps to extract a helper class or method:

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

Then you can do:

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

It might be better to use a real BlockingQueue and find a way to insert the desired value into the queue before the method that you expect to remove data from the queue.

撩发小公举 2024-09-23 04:04:28

很难确切地说出你的代码是什么样的。如果我知道您想要测试的代码,可以更好地帮助您..但是假设您想要测试的代码如下所示:

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 );



}

如果这不正确, 抱歉,但很难建议对我想要测试的代码进行测试看不到...

编辑 - 我们不能真正断言可变参数会因为我们使用模拟的方式而改变。我们所能做的就是断言drainTo方法被调用。如果drainTo做了我们想做的事情,则必须在其他地方进行测试..即在BlockingQueue.class

编辑2的测试中-我们可以更具体地了解我们期望调用该方法的列表。

hard to tell exactly what your code looks like. Could help you better if I knew the code you want to test.. but assuming your code you want to test looks like this:

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 );
}

A test would be

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 );



}

Sorry if that isn't right, but really hard to suggest a test for code that I can't see...

Edit - we can't really assert that the mutable param gets changed becuase of how we are using the mock. All we can do is assert that the drainTo method gets called. If drainTo does what we want to do would have to be tested elsewhere.. i.e. in the tests of BlockingQueue.class

Edit 2 - we can be more specific about what list we expect the method to get called with.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文