Powermockito私有方法mock NullPointerException。调用私有方法

时间:2017-11-20 11:20:38

标签: java unit-testing junit mocking powermockito

我试图模拟一个私有方法(executeGetRequest),并且在我声明我想要为私有方法返回的模拟行中,私有方法实际上是用null参数执行的,因此抛出NullPointerException。

VlcPlayerMinimal.java:

            let ridesClient = RidesClient()

            let pickupLocation = CLLocation(latitude: 37.787654, longitude: -122.402760)
            let dropoffLocation = CLLocation(latitude: 37.775200, longitude: -122.417587)
            let builder = RideParametersBuilder()
            builder.pickupLocation = pickupLocation
            builder.dropoffLocation = dropoffLocation

            ridesClient.fetchProducts(pickupLocation: pickupLocation) { products, response in
                print(response.response)
                print(products)
                guard let uberX = products.filter({$0.productGroup == .uberX}).first else {
                    // Handle error, UberX does not exist at this location
                    return
                }
                builder.productID = uberX.productID
                ridesClient.fetchRideRequestEstimate(parameters: builder.build(), completion: { rideEstimate, response in
                    guard let rideEstimate = rideEstimate else {
                        // Handle error, unable to get an ride request estimate
                        return
                    }
                    builder.upfrontFare = rideEstimate.fare
                    self.ridesClient.requestRide(parameters: builder.build(), completion: { ride, response in
                        guard let ride = ride else {
                            // Handle error, unable to request ride
                            return
                        }
                        // Ride has been requested!
                    })
                })
            }

            // Completion block. If accessToken is non-nil, you’re good to go
            // Otherwise, error.code corresponds to the RidesAuthenticationErrorType that occured
        })
    } 



   https://api.uber.com/v1.2/products?latitude=37.787654&longitude=-122.40276 } { Status Code: 401, Headers {
        Connection =     (
            "keep-alive"
        );
        "Content-Length" =     (
            63
        );
        "Content-Type" =     (
            "application/json"
        );
        Date =     (
            "Mon, 20 Nov 2017 11:08:29 GMT"
        );
        Server =     (
            nginx
        );
        "Strict-Transport-Security" =     (
            "max-age=604800"
        );
        "X-Content-Type-Options" =     (
            nosniff
        );
        "X-XSS-Protection" =     (
            "1; mode=block"
        );
    } })

VlcPlayerMinimalTest.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 { 
  }
}

堆栈追踪:

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.");
    }
  }
}

看来PowerMockito实际上正在调用我试图在PowerMockito.doReturn(" {status:stopped,id:2}")行中模拟的方法。(vlcPlayerSpy, " executeGetRequest",any(),any());

它抛出异常因为客户端为空,所以它在null上调用execute(getClient),但那是我试图避免调用的方法测试。

任何想法如何解决这个问题?我一直试着没有成功。

我使用的是Java 8,powermock 1.7.3和junit 4.12

1 个答案:

答案 0 :(得分:4)

此测试成功:

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.");
    }
  }
}

您需要这些级别注释:

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

控制台输出:

  

{status:stopped,id:2}

enter image description here