Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stubbing defaults in Mockito

How can I stub a method such that when given a value I'm not expecting, it returns a default value?

For example:

Map<String, String> map = mock(Map.class);
when(map.get("abcd")).thenReturn("defg");
when(map.get("defg")).thenReturn("ghij");
when(map.get(anyString())).thenReturn("I don't know that string");

Part 2: As above but throws an exception:

Map<String, String> map = mock(Map.class);
when(map.get("abcd")).thenReturn("defg");
when(map.get("defg")).thenReturn("ghij");
when(map.get(anyString())).thenThrow(new IllegalArgumentException("I don't know that string"));

In the above examples, the last stub takes precedence so the map will always return the default.

like image 608
Alex Spurling Avatar asked Nov 18 '10 15:11

Alex Spurling


People also ask

What is stubbing in Mockito?

A stub is a fake class that comes with preprogrammed return values. It's injected into the class under test to give you absolute control over what's being tested as input. A typical stub is a database connection that allows you to mimic any scenario without having a real database.

What is strict stubbing in Mockito?

"Strict stubbing" is a new feature in Mockito 2 that drives cleaner tests and better productivity. The easiest way to leverage it is via Mockito's JUnit support ( MockitoJUnit ) or Mockito Session ( MockitoSession ).

What is lenient () in Mockito?

lenient() to enable the lenient stubbing on the add method of our mock list. Lenient stubs bypass “strict stubbing” validation rules. For example, when stubbing is declared as lenient, it won't be checked for potential stubbing problems, such as the unnecessary stubbing described earlier.

How do you use lenient?

Lenient sentence example. The way was further prepared by a lenient use of the penal laws. He was as lenient with the offences iof the orthodox as he was rigid in suppressing heresy and schism.


2 Answers

The best solution I have found is to reverse the order of the stubs:

Map<String, String> map = mock(Map.class);
when(map.get(anyString())).thenReturn("I don't know that string");
when(map.get("abcd")).thenReturn("defg");
when(map.get("defg")).thenReturn("ghij");

When the default is to throw an exception you can just use doThrow and doReturn

doThrow(new RuntimeException()).when(map).get(anyString());
doReturn("defg").when(map).get("abcd");
doReturn("ghij").when(map).get("defg");

https://static.javadoc.io/org.mockito/mockito-core/2.18.3/org/mockito/Mockito.html#12

like image 184
Alex Spurling Avatar answered Sep 21 '22 07:09

Alex Spurling


when(map.get(anyString())).thenAnswer(new Answer<String>() {
    public String answer(Invocation invocation) {
        String arg = (String) invocation.getArguments()[0];
        if (args.equals("abcd")
             return "defg";
        // etc.
        else
             return "default";
             // or throw new Exception()
    }
});

It's kind of a roundabout way to do this. But it should work.

like image 35
shoebox639 Avatar answered Sep 19 '22 07:09

shoebox639