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

Only one method invocation is expected when testing runtime exceptions

    XMLWordPrintable

    Details

    • Type: Code Smell 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:
      Major
    • Impact:
      Low
    • Likelihood:
      High
    • Default Quality Profiles:
      Sonar way
    • Covered Languages:
      Java
    • Remediation Function:
      Constant/Issue
    • Constant Cost:
      5min
    • Analysis Scope:
      Test Sources

      Description

      When verifying that code raises a runtime exception, a good practice is to avoid having multiple method calls inside the tested code, to be explicit about which method call is expected to raise the exception.

      It increases the clarity of the test, and avoid incorrect testing when another method is actually raising the exception.

      Noncompliant Code Example

      @Test
      public void testToString() {
        // Do you expect get() or toString() throwing the exception?
        org.junit.Assert.assertThrows(IndexOutOfBoundsException.class, () -> get().toString()); 
      }
      
      @Test
      public void testToStringTryCatchIdiom() {
        try {
          // Do you expect get() or toString() throwing the exception?
          get().toString(); 
          Assert.fail("Expected an IndexOutOfBoundsException to be thrown");
        } catch (IndexOutOfBoundsException e) {
          // Test exception message...
        }
      }
      

      Compliant Solution

      @Test
      public void testToString() {
         Object obj = get();
         Assert.assertThrows(IndexOutOfBoundsException.class, () -> obj.toString());
      }
      
      @Test
      public void testToStringTryCatchIdiom() {
        Object obj = get();
        try {
          obj.toString();
          Assert.fail("Expected an IndexOutOfBoundsException to be thrown");
        } catch (IndexOutOfBoundsException e) {
          // Test exception message...
        }
      }
      

      See

        Attachments

          Issue Links

            Activity

              People

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

                Dates

                Created:
                Updated: