Mockito verify method was called with set, that contains specific value
Asked Answered
T

3

6

I want to be sure that mocked is called with specific set of strings as parameter. For example, I have the following code:

public class SomeLogic {
    @Autowired
    private SpecificService specificService;

    public void action() {
        Set<String> args = fillArgsMethod();
        specificService.handleArgs(args);
    }
}

And my current try to test it is the following

@Mock
private SpecificService specificService
@InjectMocks
private SomeLogic someLogic;

@Test
public void testAction() {
    someLogic.action();
    verify(specificService).handleArgs(anySet());
}

But I want to be sure, that handleArgs() will receive the exact set of strings, that I expect. How can I modify verifying to check that handleArgs is called with set "first","second"? Thanks

Treaty answered 16/4, 2014 at 8:19 Comment(0)
C
10

Prepare your Set parameters before calling the test method

    @Test
    public void testAction() {
        Set<String> expectedParams = new HashSet(Arrays.asList("first", "second");
        //call tested method
        verify(specificService).handleArgs(expectedParams);
    }
Conic answered 16/4, 2014 at 8:23 Comment(2)
Thanks, I thought that I need Hamcrest methods, but the solution appeared to be much more simplierTreaty
You're welcome. I use Hamcrest because it has better matchers and better reporting when a test fails.Conic
N
11

Isah gave a valid answer, but I want to turn your attention to a more general feature of Mockito which is ArgumentCaptor

In you case you would do something along the following lines:

Class<HashSet<String>> setClass = (Class<HashSet<String>>)(Class)HashSet.class;
ArgumentCaptor<Set<String>> setCaptor= ArgumentCaptor.forClass(setClass .class);

verify(specificService).create(setCaptor.capture());
HashSet<String> capturedSet = setCaptor.getValue();

//do whatever test you want with capturedSet
Neighboring answered 16/4, 2014 at 8:32 Comment(1)
In this case it is probably overkill, but you get the general idea of how this is a more general solution :)Neighboring
C
10

Prepare your Set parameters before calling the test method

    @Test
    public void testAction() {
        Set<String> expectedParams = new HashSet(Arrays.asList("first", "second");
        //call tested method
        verify(specificService).handleArgs(expectedParams);
    }
Conic answered 16/4, 2014 at 8:23 Comment(2)
Thanks, I thought that I need Hamcrest methods, but the solution appeared to be much more simplierTreaty
You're welcome. I use Hamcrest because it has better matchers and better reporting when a test fails.Conic
E
9

isah's solution is perfect for you if you want to confirm that the set contains exactly the two items you specify; Mockito compares using .equals by default, and Set.equals is defined as refer to equal elements in any order.

For a more-flexible "contains" test that matches your question title, that allows for set members beyond your expected values, you can also use the Hamcrest contains matcher:

someLogic.action();
verify(specificService).handleArgs(argThat(contains("first", "second")));

At least, that's how it should look. Unfortunately, argThat infers its return type from the Matcher, which infers its return type from the arguments, so Java assumes your first argument is not a Set<String> but a Iterable<capture#1-of ? extends String>. You'll need to cast explicitly and suppress warnings to get it to work:

// requires @SuppressWarnings("unchecked")
verify(specificService).handleArgs(
    (Set<String>) argThat(contains("first", "second")));
Edmiston answered 16/4, 2014 at 14:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.