EasyMock and change parameter of mutable method

How to use EasyMock to change a method parameter of a mutable method?

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

+6
java unit-testing junit easymock
source share
2 answers

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

Sometimes this 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 is 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.

+12
source share

it's hard to pinpoint what your code looks like. May help you better if I knew the code you want to test. But if 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 ); } 

Test will 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 this is wrong, but it is very difficult to offer a test for code that I do not see ...

Change - we cannot claim that the parameter being changed is changing because we use the layout. All we can do is claim that the drainage method is called. If drainTo does what we want to do, we’ll have to test it elsewhere, i.e. in BlockingQueue.class tests

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

0
source share

All Articles