Uploaded image for project: 'Rules Repository'
  1. Rules Repository
  2. RSPEC-6073

Mockito argument matchers should be used on all parameters

    XMLWordPrintable

    Details

    • Type: Bug Detection
    • Status: Active
    • Resolution: Unresolved
    • Labels:
    • Message:
      Hide
      Add an "eq()" argument matcher on this/these parameters
      Show
      Add an "eq()" argument matcher on this/these parameters
    • Highlighting:
      Hide

      primary: the first parameter without argument matchers
      secondary: all the other parameters without argument matchers

      Show
      primary: the first parameter without argument matchers secondary: all the other parameters without argument matchers
    • Default Severity:
      Major
    • Impact:
      Low
    • Likelihood:
      High
    • Covered Languages:
      Java
    • Irrelevant for Languages:
      ABAP, APEX, C#, C, C++, Cobol, CSS, Flex, Go, HTML, JavaScript, Kotlin, Objective-C, PHP, PL/I, PL/SQL, Python, RPG, Ruby, Rust, Scala, Solidity, Swift, T-SQL, TypeScript, VB.Net, VB6, XML
    • Remediation Function:
      Constant/Issue
    • Constant Cost:
      5min
    • Analysis Level:
      Syntactic Analysis
    • Analysis Scope:
      Test Sources

      Description

      Mockito provides argument matchers and argument captors for flexibly stubbing or verifying method calls.

      Mockito.verify(), Mockito.when(), Stubber.when() and BDDMockito.given() each have overloads with and without argument matchers.

      However, if argument matchers or captors are used only on some of the parameters, all the parameters need to have matchers as well, otherwise an InvalidUseOfMatchersException will be thrown.

      This rule consequently raises an issue every time matchers are not used on all the parameters of a stubbed/verified method.

      Noncompliant Code Example

      @Test
      public void myTest() {
        given(foo.bar(anyInt(), i1, i2)).willReturn(null); // Noncompliant
        when(foo.baz(eq(val1), val2)).thenReturn("hi"); // Noncompliant
        doThrow(new RuntimeException()).when(foo).quux(intThat(x -> x >= 42), -1); // Noncompliant
        verify(foo).bar(i1, anyInt(), i2); // Noncompliant
        ArgumentCaptor<Integer> captor = ArgumentCaptor.forClass(Integer.class);
        verify(foo).bar(captor.capture(), i1, any()); // Noncompliant
      }
      

      Compliant Solution

      @Test
      public void myTest() {
        given(foo.bar(anyInt(), eq(i1), eq(i2))).willReturn(null);
        when(foo.baz(val1, val2)).thenReturn("hi");
        doThrow(new RuntimeException()).when(foo).quux(intThat(x -> x >= 42), eq(-1));
        verify(foo).bar(eq(i1), anyInt(), eq(i2));
        ArgumentCaptor<Integer> captor = ArgumentCaptor.forClass(Integer.class);
        verify(foo).bar(captor.capture(), any(), any());
      }
      

      See

      • Mockito documentation - argument matchers
      • S6068 - Call to Mockito method "verify", "when" or "given" should be simplified

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              Unassigned Unassigned
              Reporter:
              michael.gumowski Michael Gumowski
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Dates

                Created:
                Updated: