0

I need to mock a protected method in the parent class of my class under test but the parent class is in a different package. I thought that the solution would be to use PowerMockito.spy() but I cannot instantiate the type Child because it is abstract. There's gotta be a solution for this issue without refactoring.

Here's the Dependencies.

        <dependency org="org.powermock" name="powermock-core" rev="1.6.4"/>
        <dependency org="org.powermock" name="powermock-module-junit4" rev="1.6.4"/>
        <dependency org="org.powermock" name="powermock-api-mockito" rev="1.6.4"/> 

This is legacy code so I cannot refactor, but here's the simplified code.

Parent.java

package parent;

public class Parent {

    // Want to mock this protected parent method from different package
    protected String foo() {

        String someValue = null;

        // Logic setting someValue

        return someValue;
    }
}

Child.java

package child;

import parent.Parent;

public abstract class Child extends Parent {

    String fooString = null;

    public String boo() {

        this.fooString = this.foo();

        String booString = null;

        // Logic setting booString

        return booString;
    }
}
javaPlease42
  • 4,699
  • 7
  • 36
  • 65
  • 1
    Every time some dev writes `String xxx = null`, a kitten dies. Regarding the question, I read it 3 times and I'm sorry but I don't understand what you are asking. Are you asking how to instantiate an abstract class? –  Jul 26 '16 at 17:53
  • haha I just threw together a quick example. It is similar to this [question](http://stackoverflow.com/questions/34684328/mock-protected-parent-method-when-the-parent-is-in-a-different-package?rq=1) but I cannot use `PowerMockito.spy()` here because the class under test is abstract. – javaPlease42 Jul 26 '16 at 18:02
  • So I want to mock the `Parent.boo()` method and my class under test is `Child`. So I need to use `Mockito.spy(Child.class)` instead of `PowerMockito.spy(new Child())` because Child is abstract. – javaPlease42 Jul 26 '16 at 18:06
  • http://static.javadoc.io/org.powermock/powermock-api-mockito/1.6.2/org/powermock/api/mockito/PowerMockito.html#spy-java.lang.Class- ? –  Jul 26 '16 at 18:17
  • I want the answer to be in the form of implementing the solution in a JUnit test called `ChildTest.java` please. – javaPlease42 Jul 26 '16 at 18:24
  • I also want some gremlins to do my job but that's not the way it works.. –  Jul 26 '16 at 18:30
  • I will throw together `ChildTest.java` soon to make my question more clear. – javaPlease42 Jul 26 '16 at 18:32
  • I usually have the [same structure in my tests as in my production classes](http://c2.com/cgi/wiki?AbstractTestCases). Meaning I have an abstract test which verifies common behaviour, and a concrete test for each class which (at least) instantiates the correct object under test and verifies any custom behaviour (if any). – Morfic Jul 28 '16 at 08:46
  • Hint: you seriously want to read about the open/closed principle; and from there: rework your code to not be a bad design which leads to such testing problems. You see, if code is hard to test, it is most likely also hard to use, maintain and inherently smelly ... – GhostCat Jul 28 '16 at 11:41

1 Answers1

0

You can use PowerMock to mock methods that are not public

@RunWith(PowerMockRunner.class)
public class ChildTest {

   @Test
   public void testBoo() throws Exception {
      Child child = PowerMockito.mock(Child.class);
      PowerMockito.when(child, "foo").thenReturn("someValue");
      PowerMockito.doCallRealMethod().when(child).boo()
      String boo = child.boo();

      //assert here whatever you want to assert
   }
}
Rodrigo Villalba Zayas
  • 5,326
  • 2
  • 23
  • 36