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

Only one method invocation is expected when testing checked exceptions

    XMLWordPrintable

    Details

    • Type: Bug Detection
    • Status: Active
    • Resolution: Unresolved
    • Labels:
    • Message:
      Refactor {the body of this try/catch|the code of this assertThrows} to have only one invocation throwing an exception.
    • Highlighting:
      • Primary: assertThrows/try keyword
      • Secondaries: Methods calls
    • Default Severity:
      Critical
    • Impact:
      High
    • Likelihood:
      Low
    • Covered Languages:
      Java, PHP
    • Remediation Function:
      Constant/Issue
    • Constant Cost:
      5min
    • Analysis Scope:
      Test Sources

      Description

      When verifying that code raises an exception, a good practice is to avoid having multiple method calls inside the tested code, to be explicit about what is exactly tested.

      When two of the methods can raise the same checked exception, not respecting this good practice is a bug, since it is not possible to know what is really tested.

      You should make sure that only one method can raise the expected checked exception in the tested code.

      Noncompliant Code Example

      @Test
      public void testG() {
        // Do you expect g() or f() throwing the exception?
        assertThrows(IOException.class, () -> g(f(1)) ); // Noncompliant
      }
      
      @Test
      public void testGTryCatchIdiom() {
        try { // Noncompliant
          g(f(1)); 
          Assert.fail("Expected an IOException to be thrown");
        } catch (IOException e) {
          // Test exception message...
        }
      }
      
      int f(int x) throws IOException {
        // ...
      }
      
      int g(int x) throws IOException {
        // ...
      }
      

      Compliant Solution

      @Test
      public void testG() {
        int y = f(1);
        // It is explicit that we expect an exception from g() and not f()
        assertThrows(IOException.class, () -> g(y) );
      }
      
      @Test
      public void testGTryCatchIdiom() {
        int y = f(1);
        try {
          g(y); 
          Assert.fail("Expected an IOException to be thrown");
        } catch (IOException e) {
          // Test exception message...
        }
      }
      

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              Unassigned Unassigned
              Reporter:
              quentin.jaquier Quentin Jaquier
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Dates

                Created:
                Updated: