Interacting with an argument passed to a mocked method in EasyMock

I don’t know EasyMock very well, I just use what I know. I hear you saying;

C’mon man, how hard can it be? Besides the whole library consists of 11 classes. Just read the manual and the API docs.

I hear you, however I could not find that time ever. I found my own ways when I found myself in situations that can not be handled with EasyMock –my view of EasyMock of course–

For example, there is this problem that I always faced with. When you need to provide a custom behavior only for one method of an interface –since you can not do this with EasyMock, at least according to my knowledge–, I would create a mock implementation just to override that particular method. BTW don’t get mistaken it is also not that easy with EasyMock, I am talking about interacting with an argument of a mocked method which itself is created by some class and passed as an argument to that method by a method that you don’t have control over.

Let me demonstrate it with an example. Let’s say I have a ContentReader class that reads a content from somewhere with some utility methods.

And let’s say I have another class which is also the class that I want to test. This class is the class calling the readContent(File file) method. The intention is to dump the content to a temporary file, pass the absolute path of this file to a utility method to extract metadata about the content. I agree in the first place why I am dumping the content to a temporary file and passing the absolute path to this metadata extractor instead of passing the stream directly, right? You should ask this to the developers of im4java, not me:)

READ  Linux Bash get IP address

Anyway, this time when I faced a similar problem, I decided to check the EasyMock documentation to find something that can solve this problem instead of blindly doing the same thing I do always. There are a lot of stuff argument matcher, expectations, controls to also verify the calling order, etc. However I could not find something that I can use to inject some behavior to a mocked method to work on an argument passed to that mocked method. But I found two interesting things;

  • capture(Capture<T> captured) for capturing arguments of a mocked method. The main use case of capture is to verify the argument using your own way instead of trying to fit your expectations to the limited set provided by EasyMock.
  • IExpectationSetters<T> andAnswer(IAnswer<? extends T> answer) for setting an object that can calculate the return value.

They don’t help me unless I use them together. What if

  • We capture the file using capture in a final variable
  • We use answer to interact with the captured value

It is an workaround but a nice one, admit it.

Unfortunately it is not possible to use expect method for a method that returns void. Luckily unlike expect, expectLastCall does. Now I can use capture to get a handle to the argument passed and interact with it using you IAnswer implementation. See the following example.

READ  Fancybox on Web Forms

Finally since the method returns void, you have to return null from IAnswer.

The latest example is as follows, it is modified according to Meltem’s feedback. There is no need to capture the variable you want to interact using capture() to a final variable –unless you want to share it within your test method–, you can simple call getCurrentArguments() method while you are inside IAnswer.answer().

Leave a Reply

Your email address will not be published. Required fields are marked *