Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Powermockito private method mock NullPointerException. Calls the private method

Tags:

I'm trying to mock a private method (executeGetRequest) and in the line that I'm declaring the mock that I want returned for the private method, the private method is actually being executed with null arguments, therefore throwing a NullPointerException.

VlcPlayerMinimal.java:

package com.nicobrest.kamehouse.vlcrc.model;

public class VlcPlayerMinimal {

  public static void main(String[] args) {
    String vlcRcStatus = new VlcPlayerMinimal().getVlcRcStatus();
    System.out.println(vlcRcStatus);
  }

  public String getVlcRcStatus() {
    Client client = new Client();
    GetRequest getRequest = new GetRequest();
    String vlcRcStatus = executeGetRequest(client, getRequest);
    return vlcRcStatus;
  }

  private String executeGetRequest(Client client, GetRequest getRequest) {
    return client.execute(getRequest);
  }

  private class Client {
    public String execute(GetRequest getRequest) {
      return "{status: playing, id: 1}";
    }
  }
  private class GetRequest { 
  }
}

VlcPlayerMinimalTest.java:

package com.nicobrest.kamehouse.model;

import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.any;

import com.nicobrest.kamehouse.vlcrc.model.VlcPlayerMinimal;

import org.junit.Test;
import org.powermock.api.mockito.PowerMockito;

public class VlcPlayerMinimalTest {

  @Test
  public void getVlcRcStatusTest() {
    VlcPlayerMinimal vlcPlayerSpy = PowerMockito.spy(new VlcPlayerMinimal());
    try {
      PowerMockito.doReturn("{status: stopped, id: 2}").when(vlcPlayerSpy, "executeGetRequest", any(), any());
      String vlcRcStatus = vlcPlayerSpy.getVlcRcStatus();
      System.out.println(vlcRcStatus);
    } catch (Exception e) {
      e.printStackTrace();
      fail("Unexpected exception thrown.");
    }
  }
}

Stack trace:

java.lang.NullPointerException
    at com.nicobrest.kamehouse.vlcrc.model.VlcPlayerMinimal.executeGetRequest(VlcPlayerMinimal.java:18)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.powermock.reflect.internal.WhiteboxImpl.performMethodInvocation(WhiteboxImpl.java:1846)
    at org.powermock.reflect.internal.WhiteboxImpl.doInvokeMethod(WhiteboxImpl.java:810)
    at org.powermock.reflect.internal.WhiteboxImpl.invokeMethod(WhiteboxImpl.java:675)
    at org.powermock.reflect.Whitebox.invokeMethod(Whitebox.java:401)
    at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.when(PowerMockitoStubberImpl.java:95)
    at com.nicobrest.kamehouse.model.VlcPlayerMinimalTest.getVlcRcStatusTest(VlcPlayerMinimalTest.java:17)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...

It appears PowerMockito is actually calling the method that I'm trying to mock in the line PowerMockito.doReturn("{status: stopped, id: 2}").when(vlcPlayerSpy, "executeGetRequest", any(), any());

And it's throwing the exception because client is null, so it's calling execute(getClient) on null, but that's the method I'm trying to avoid to call in the test.

Any ideas how to fix this? I've been trying for a while without success.

I'm using Java 8, powermock 1.7.3 and junit 4.12

like image 878
nbrest Avatar asked Nov 20 '17 11:11

nbrest


1 Answers

This Test is Succesful:

package foo.bar;

import static org.junit.Assert.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(VlcPlayerMinimal.class)
public class VlcPlayerMinimalTest {

  @Test
  public void getVlcRcStatusTest() {
    VlcPlayerMinimal vlcPlayerSpy = PowerMockito.spy(new VlcPlayerMinimal());
    try {
      PowerMockito.doReturn("{status: stopped, id: 2}").when(vlcPlayerSpy, "executeGetRequest", Mockito.any(), Mockito.any());
      String vlcRcStatus = vlcPlayerSpy.getVlcRcStatus();
      System.out.println(vlcRcStatus);
    } catch (Exception e) {
      e.printStackTrace();
      fail("Unexpected exception thrown.");
    }
  }
}

You need these Class Level Annotations:

@RunWith(PowerMockRunner.class)
@PrepareForTest(VlcPlayerMinimal.class)

Console Output:

{status: stopped, id: 2}

enter image description here

like image 158
javaPlease42 Avatar answered Sep 22 '22 13:09

javaPlease42