Problem with Java Rule S6073: "Mockito argument matchers..." in case of usage MockitoHamcrest adapter

Hello dear SonarSource,
based on the Ticket SONARJAVA-3614, as I written there, we’ve got a troubles with Rule S6073: Mockito argument matchers should be used on all parameters in case if org.mockito.hamcrest.MockitoHamcrest is used.

E.g. I have class like followed:

import java.net.URI;
import java.util.Arrays;
import java.util.stream.Collectors;

import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.lang.NonNull;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.client.RestTemplate;

import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.Matchers.instanceOf;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.when;
import static org.mockito.hamcrest.MockitoHamcrest.argThat;

@RunWith(SpringRunner.class)
public class MyTestClass {

    @MockBean
    protected RestTemplate restTemplate;

    @Test
    public void should_succeed_integration_on_created_items() {
        final Matcher<URI> matchesStreamsEnableUrl = matchesUrlByPathEnd("/stream-test-tag1-id/resume",
                                                                         "/stream-test-tag2-id/resume");

        when(restTemplate.postForEntity(argThat(matchesStreamsEnableUrl), isNull(), eq(Object.class)))
                .thenReturn(new ResponseEntity<>(HttpStatus.NO_CONTENT));
    }

    protected Matcher<URI> matchesUrlByPathEnd(final @NonNull String... pathEnd) {
        final Iterable<Matcher<? super String>> pathMatchers = Arrays.stream(pathEnd)
                .map(Matchers::endsWith)
                .collect(Collectors.toList());

        return allOf(instanceOf(URI.class), hasProperty("path", anyOf(pathMatchers)));
    }
}

Sonar marks all argThat( SOME_HAMCREST_MATCHER ) with “SonarLint: Add an “eq()” argument matcher on these parameters”

We have hundreds of such calls, where MockitoHamcrest.argThat( SOME_HAMCREST_MATCHER ) is used inside of Mockito.when()

We use SonarCloud with default Sonar way quality profile, but needed to create own profile, because of hundreds of major code smells across multiple projects.
Please disable or fix this rule, as this bridge between Mockito and Hamcrest is proper one

Hello @m.kyrychenko, thanks again reporting this issue here.
Could you share which version of mockito and hamcrest you are using in these tests?

Dorian

Hi @Dorian_Burihabwa hamcrest version doesn’t really matter as I have a similar issue even without hamcrest.
Mockito version is 3.3.3 but also not really relevant here.

Here is my code causing the same trouble:

Mockito.verify(myClass).doSomething(contains("Apple"), anyBoolean());

private Collection<String> contains(String fruit) {
    return argThat(input -> !input.isEmpty() && input.contains(fruit));
}

class MyClass {
    public boolean doSomething(Collection<String> fruits, boolean isSonarGreat) {
       return isSonarGreat ? true : fruits.isEmpty();
    }
}

Hello,

I just stumbled into this rather old topic and decided to have a closer look.

I think the two samples code are actually two different problems.

The first one is due to the fact that we are not supporting correctly org.mockito.hamcrest.MockitoHamcrest.argThat. Ticket created: SONARJAVA-4221

The second one is probably related to SONARJAVA-3822. Note that if the method contains(String) is in another file, it will not work as expected.

In any way, we are aware that this rule can be imprecise, it was meant for beginners with Mockito, if you know what you are doing, you probably don’t need it. This is exactly why it is no longer in the default quality profile.

Hope it clarifies the situation.
Best,
Quentin

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.