3

I have the following interface:

public interface Test{
    public void block(String modifier);
    public boolean blocked(String modifier);
}

So I wanted to mock this interface as follows:

Test m = Mockito.mock(Test.class);
when(m.blocked(Mockito.any()).thenReturn(true);
//I want to mock m.block()

Buty I want to mock Test::block(String) the way so when it is called on some String someString it changes the behavior so that m.blocked(someString) will return false.

Is it possible to do so in Mockito?

  • 1
    You could have a boolean field, and rather then use thenReturn, use thenAnswer and create a logic using this field – Paedolos Nov 22 '17 at 22:46
  • 1
    https://stackoverflow.com/questions/26067096/how-to-write-a-matcher-that-is-not-equal-to-something – ronhash Nov 22 '17 at 22:48

2 Answers2

4

You can use thenAnswer and doAnswer to execute arbitrary code when a method is called. For example, you could use a Set to keep track of the strings that have already been blocked:

Set<Object> blocked = new HashSet<>();
Test m = mock(Test.class);
doAnswer(invocation -> blocked.add(invocation.getArguments()[0]))
    .when(m).block(any());
when(m.blocked(any()))
    .thenAnswer(invocation -> !blocked.contains(invocation.getArguments()[0]));
Mureinik
  • 297,002
  • 52
  • 306
  • 350
1

Here's a sample, assuming you have a boolean field that starts as true --

when(m.blocked(Mockito.any()).thenAnswer(invocation -> this.mockValue);
when(m.block(Mockito.eq("Some String")).thenAnswer(invocation -> {
    this.mockValue = false;
    return null;
});

Hopefully I didn't get the syntax wrong :-)

Paedolos
  • 270
  • 1
  • 6