使用 Powermockito 在 junit 中模拟私有方法

Mocking a private method in junit using Powermockito

我需要模拟以下方法调用 carBookBuilder.setTrip(protoConverter.convertTrip(carBookRequest, location)),但是当 carBookBuilder.setTrip(protoConverter.convertTrip(carBookRequest, location)) 调用时我应该 return 模拟 tripdetails 并跳过 protoConverter.convertTrip(carBookRequest, location) 方法调用。

ProtoRequestAdapterTest.java

@RunWith(PowerMockRunner.class)
@PrepareForTest({ProtoRequestAdapter})
class ProtoRequestAdapterTest {

    @Test
    public void testPopulateCarBookTest() {
        CarApiToProtoConverter carApiToProtoConverter;
        carApiToProtoConverter =  PowerMockito.mock(CarApiToProtoConverter.class);
        PowerMockito.when(carApiToProtoConverter.convertTripDetails(carBookRequest, locale)).thenReturn(tripDetails);
    }
}

ProtoRequestAdapter.java

class ProtoRequestAdapter {
     private CarBookRequest populateCarBook(BookingRequest bookingRequest) {
        CarBookRequest newCarBookReq = bookingRequest.getCarBookRequest();
        CarBookRequest.Builder carBookBuilder = CarBookRequest.newBuilder();

        ProtoConverter protoConverter =
                new ProtoConverter(refData, location);
        carBookBuilder.setTrip(protoConverter.convertTrip(carBookRequest, location));
        return carBookBuilder;
    }
}

您必须在测试中实例化 tripDetails class。

TripDetails tripDetails = new TripDetails();
tripDetails.setLocation = "London";

我在这里看到了几个问题。 如果我理解正确的话,你正在尝试测试 ProtoRequestAdapter#populateCarBook.

首先你应该使方法 public 或至少受到保护,否则你的单元测试无法调用它。

接下来您要模拟的方法是 ProtoConverter#convertTrip,它不是私有的,否则您的代码将无法编译。 更有问题的是你直接在你的代码中实例化它,这使得它无法用模拟来替换它。

我强烈建议您将它注入到您的 class 中(或者至少将实例化移动到一个(受保护的)getProtoConverter() 方法中,您可以在测试中覆盖它)。