fwind fwind - 1 year ago 62
Java Question

First stub is called when adding an additional stub

I have the following object which I want to test:

public class MyObject {

Downloader downloader;

public List<String> readFiles(String[] fileNames) {
List<String> files = new LinkedList<>();
for (String fileName : fileNames) {
try {
} catch (IOException e) {
return files;

This is my test:

public class mockTest {

@Inject Downloader downloader;
@Inject MyObject myObject;

private final String[] FILE_NAMES = new String[] {"fail", "fail", "testFile"};
private final List<String> EXPECTED_FILES = Arrays.asList("NA", "NA", "mockContent");

public void testException() throws IOException {
.thenThrow(new IOException());



public static final class MyTestModule extends TestModule {
protected void configureTest() {

I am overwriting the
matcher for a specific argument. I am stubbing the
method so that it returns a value for a specific argument and otherwise throws an IOException which gets handled by

The weird thing here is that the second stub (
) throws the IOException set in the first stub (
). I have validated that by throwing a different exception in my first stub.

Can someone explain me why the exception is thrown when adding an additional stub? I thought that creating a stub does not call the method/other stubs.

Answer Source

I thought that creating a stub does not call the method/other stubs.

This assumption is wrong, because stubbing is calling the mocks methods. Your test methods are still plain java!

Since stubbing for anyString will overwrite stubbing for any specific string you will either have to write two tests or stub for two specific arguments:

when(downloader.download("fail")).thenThrow(new IOException());


Mockito is a very sophisticated piece of code that tries its best so that you can write

when(downloader.download(anyString())).thenThrow(new IOException());

which means “when the downloaders mock download method is called with anyString argument thenThrow an IOException” (i.e. it can be read from left to right).

However, since the code is still plain java, the call sequence actually is:

String s1 = anyString(); // 1
String s2 = downloader.download(s1); // 2
when(s2).thenThrow(new IOException()); // 3

Behind the scenes, Mockito needs to do this:

  1. register an ArgumentMatcher for any String argument
  2. register a method call download on the downloader mock where the argument is defined by the previously registered ArgumentMatcher
  3. register an action for the previously registered method call on a mock

If you now call

 ... downloader.download("testFile") ...

the downloader mock checks whether there is an action register for "testFile" (there is, since there is already an action for any String) and accordingly throws the IOException.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download