Java – Using Mockito test super class method

javamockingmockitounit testing


    class Sup {
          public void someMethod(){
              // do something
          }
    }


    class Sub extends Sup {
            public void method(Object obj) {
                  if (obj == null) {
                      super.someMethod();
                      return;
                  }

                 // do something
            }
    }


    class SubTest {

        @Test
        public void testMethodArgIsNull() {
                 Sub s = new Sub();
                 Sub spyS = spy(s);

                 spyS.method(null);

                 //test case fails
                 verify(spyS).someMethod();

         }
    }

if I redefine the method "method" in Sub like, instead of calling super.someMethod(), if i call someMethod(), the test case passed. But I don't want to make any changes in code. help me to test the code..

Best Answer

I don't know why you want to avoid changing code, but you may have your reasons. You can't simply verify that the super method was called on a spy. However, you may still be able to test this method without changing the code. The only way to do that, though, is without the spy. In other words, you will have to verify the functionality of someMethod with assertions or verifications on other mocks. For example, if the Sup class were implemented trivially thus:

class Sup {
      private boolean somethingDone = false;
      public boolean isSomethingDone() {
          return somethingDone;
      }

      public void someMethod(){
          somethingDone = true;
      }
}

Then you could write your test case thus:

@Test
public void testMethodArgIsNull() {
    Sub s = new Sub();
    s.method(null);
    assertThat(s.isSomethingDone(), is(true));
}

That being said, calling super.someMethod() from anything other than Sub.someMethod() (which doesn't exist) looks like a gotcha waiting to happen. If Sub.someMethod() does not exist, then super.someMethod() is equivalent to someMethod(). But, if someone were to override it in the future, would you really want method(Object o) to sneakily bypass the overridden one and call the super implementation anyway?

By calling super.someMethod() you gain nothing but risk future bugs.