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