1

I am testing a class that has a private method "getEntityManager". This method returns an entity manager instance to be used in the public method "getAllProducts". So I use PowerMockRunner; My dependencies are:

junit-4.1.2
mockito-all-1.10.19
powermock-module-junit4- 1.6.5
powermock-api-mockito-1.6.5
javassist-3.12.1.GA

Hier is my (@GhostCat enhanced) Code:

@RunWith(PowerMockRunner.class)
@PrepareForTest(ProduktDB.class)
public class ProduktDBTest {

  static final String PRODUCTID= "id";
  List<Product> productList;
  EntityManager emmock;
  Query q;

  @Before
  public void setUp() throws Exception {
    basicProductList= new ArrayList<>();
    BasicProductDao basicProductDao= new BasicProductDao();
    basicProductDao.setId(PRODUCTID);
    basicProductList.add(basicProductDao);

    emmock= mock(EntityManager.class);
    q= mock(Query.class);
  }

  @Test
  public void getAllProducts() throws Exception {
    when(emmock.createQuery(anyString())).thenReturn(q);
    when(q.getResultList()).thenReturn(productList);      
    ProduktDB spied= spy(new ProduktDB());

  /* ***********this is the line with the error:****** */
   PowerMockito.doReturn(emmock).when(spied, "getEntityManager"); 

    assertEquals(spied.getAllProducts().get(0).getId(),PRODUCTID );
  }
}

However I am getting following error when I want to add the return value on call to the private method:

java.lang.NullPointerException
at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.addAnswersForStubbing(PowerMockitoStubberImpl.java:68)

Now I change the critical line to the following:

  PowerMockito.when(spied, "getEntityManager").thenReturn(emmock);

No I get another error but it is harmless (see solution bellow). :)

saab
  • 129
  • 1
  • 3
  • 16
  • Side note: don't use "_" in variable names. Except for constants like PRODUCT_ID. And method names should be camelCase. And instead of calling a prepareList() directly, consider using @Before. Finally: if you dont get a good answer here, try the google groups for powermock. And finally: you got an exception with a line number. Don't you think it would be helpful if you told us which line in your code gives that exception? – GhostCat Aug 12 '16 at 04:35
  • Please, add full stacktrace, not only last line of exception. – Artur Zagretdinov Aug 12 '16 at 05:50

1 Answers1

1

The new error was:

 org.mockito.exceptions.misusing.MissingMethodInvocationException: 
 ...
 ...
 at org.powermock.api.extension.reporter.MockingFrameworkReporterFactoryImpl$PowerMockitoReporter.missingMethodInvocation(MockingFrameworkReporterFactoryImpl.java:66)
at de.ams.dpag.produktdb.ProduktDBAdapterTest.getAllProducts(ProduktDBAdapterTest.java:72)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at ...
....

The reason was that "getEntityManager" calls the static method of base class. I had to mocStatic(BaseclassWitStaticMethod) too, and then add the expected return value to it like this:

@PrepareForTest({ProduktDB.class, BaseClasswithStaticMethod.class})
...
    ProduktDB spied= spy(new ProduktDB());
    mockStatic(BaseClasswithStaticMethod.class);
    when(BaseClasswithStaticMethod.getEntityManager()).thenReturn(emmock);
  ...

Test passed.

saab
  • 129
  • 1
  • 3
  • 16