3

In my project Mockito.times(1) is often used when verifying mocks:

verify(mock, times(1)).call();

This is redundant since Mockito uses implicit times(1) for verify(Object), thus the following code does exactly what the code above does:

verify(mock).call();

So I'm going to write an a structural search drive inspection to report such cases (let's say, named something like Mockito.times(1) is redundant). As I'm not an expert in IntelliJ IDEA structural search, my first attempt was:

Mockito.times(1)

Obviously, this is not a good seach template because it ignores the call-site. Let's say, I find it useful for the following code and I would not like the inspection to trigger:

VerificationMode times = Mockito.times(1);
                      // ^ unwanted "Mockito.times(1) is redundant"

So now I would like to define the context where I would like the inspection to trigger. Now the inspection search template becomes:

Mockito.verify($mock$, Mockito.times(1))

Great! Now code like verify(mock, times(1)).call() is reported fine (if times was statically imported from org.mockito.Mockito). But there is also one thing. Mockito.times actually comes from its VerificationModeFactory class where such verification modes are grouped, so the following line is ignored by the inspection:

verify(mockSupplier, VerificationModeFactory.times(1)).get();

My another attempt to fix this one was something like:

Mockito.verify($mock$, $times$(1))

where:

  • $mock$ is still a default template variable;
  • $times$ is a variable with Text/regexp set to times, Whole words only and Value is read are set to true, and Expression type (regexp) is set to (Times|VerificationMode) -- at least this is the way I believed it should work.

Can't make it work. Why is Times also included to the regexp? This is the real implementation of *.times(int), so, ideally, the following line should be reported too:

verify(mockSupplier, new Times(1)).get();

Of course, I could create all three inspection templates, but is it possible to create such a template using single search template and what am I missing when configuring the $times$ variable?

(I'm using IntelliJ IDEA Community Edition 2016.1.1)

Lyubomyr Shaydariv
  • 20,327
  • 12
  • 64
  • 105

1 Answers1

2

Try the following search query:
Mockito.verify($mock$, $Qualifier$.times(1))

With $Qualifier$ text/regexp VerificationModeFactory|Mockito and occurrences count 0,1 (to find it when statically imported also).

To also match new Times(1) you can use the following query:
Mockito.verify($mock$, $times$)

With $times$ text/regexp .*times\s*\(\s*1\s*\) and uncheck the Case sensitive checkbox.

Bas Leijdekkers
  • 23,709
  • 4
  • 70
  • 68
  • Thank you for the suggestion, that's working! I would like to ask: is it possible to let the `new Times(1)` constructor also be included to the same inspection somehow? – Lyubomyr Shaydariv Sep 22 '16 at 14:06
  • I have added a way to find `new Times(1)` also to my answer. – Bas Leijdekkers Sep 22 '16 at 17:59
  • Oh, structural search seems to be heavy text/regex-oriented. I thought it's not. I would like to use your first suggestion and split it to two modifications: methods and the constructors just giving them different names. Thank you! – Lyubomyr Shaydariv Sep 22 '16 at 18:17
  • It's actually only heavy text/regex-oriented if you are trying to search for more than one thing at the same time;-) – Bas Leijdekkers Sep 22 '16 at 18:20