如何模拟太阳球衣客户端的电话?

问题描述 投票:1回答:2

这是我的代码

@Service
public class PaymentHandler {
private static final Gson GSON = new Gson();

private static Client webServiceClient = createSslClient(); // function creates a ssl connection

public Response makePayment(String payload) {
    WebResource webResource = webServiceClient.resource(url);

    WebResource.Builder builder = webResource.getRequestBuilder();

    String r = builder
            .type(MediaType.APPLICATION_JSON_TYPE)
            .accept(MediaType.APPLICATION_JSON_TYPE)
            .post(String.class, payload);

    Response response = GSON.fromJson(r, Response.class);
}
}

以下是我尝试测试不起作用的方法,它总是拨打支付服务电话。我无法嘲笑它。

Client client = mock(Client.class );
WebResource webResource = mock(WebResource.class);
WebResource.Builder builder = mock(WebResource.Builder.class);
ClientResponse clientResponse = mock(ClientResponse.class);
when(client.resource(anyString())).thenReturn(webResource);
when(webResource.getRequestBuilder()).thenReturn(builder);

when(builder.type(anyString())).thenReturn(builder);
when(builder.accept(anyString())).thenReturn(builder);
when(builder.post(Matchers.eq(String.class), anyString())).thenReturn("Test");
paymentHandler.makePayment(payload); //assume that I send actual payload

有人可以告诉我如何嘲笑这个?

java unit-testing junit mockito jersey-client
2个回答
2
投票

在您的测试中,我没有看到您用模拟版本替换webServiceClient

但首先,我相信你最好不要在没有依赖注入的情况下编写像PaymentHandler这样的代码。它可能只是一个简单的组合,webServiceClient注入PaymentHandler。没有依赖注入,它不灵活,难以维护,因此不可测试。例如,想象一下,如果这种字段的初始化需要与外部系统进行一些交互会发生什么。如果没有任何字节码操作库,您将如何测试它?或者你如何轻松地从一个webServiceClient迁移到另一个@RunWith(PowerMockRunner.class) @PrepareForTest(PaymentHandler.class) public class PaymentHandlerTest { @Test public void test() throws Exception { //we don't want to initialize the PaymentHandler.class because it might cause some //heavy undesirable initilization. E.g. if we had referred to PaymentHandler as a class //literal here, then the webServiceClient would've been initializaed with some "real" //instance of Client. My PaymentHandler is located in so package. You should specify your //fully qualified class' name here Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass("so.PaymentHandler"); //now the webServiceClient will be null once we initialize the PaymentHandler class PowerMockito.suppress(PowerMockito.method(clazz, "createSslClient")); Client client = mock(Client.class); //here we initialize the PaymentHandler.class and finally mock the webServiceClient Whitebox.setInternalState(clazz, "webServiceClient", client); PaymentHandler paymentHandler = new PaymentHandler(); WebResource webResource = mock(WebResource.class); WebResource.Builder builder = mock(WebResource.Builder.class); when(client.resource(anyString())).thenReturn(webResource); when(webResource.getRequestBuilder()).thenReturn(builder); //take note of any(MediaType.class) instead of anyString() from your example. As in //your PaymentHandler, MediaType is used instead of String when(builder.type(any(MediaType.class))).thenReturn(builder); when(builder.accept(any(MediaType.class))).thenReturn(builder); when(builder.post(Matchers.eq(String.class), anyString())).thenReturn("{}"); paymentHandler.makePayment("payload"); } } ,例如从非ssl到ssl?

尽管有这些众所周知的问题,但有时我们必须处理我们无法轻易改变的第三方或遗留代码。但我们希望为与第三方代码交互的代码编写测试。出于这个原因,存在一些很酷的测试框架。 PowerMock就是其中之一,下面是使用它的工作代码:

testCompile group: 'org.powermock', name: 'powermock-api-mockito2', version: '2.0.0'
testCompile group: 'org.powermock', name: 'powermock-module-junit4', version: '2.0.0'

在我的示例中,我使用了以下依赖项:

@Mock
Client client;

@Mock
WebResource webResource;

@Mock
WebResource.Builder builder;


@Test
public void test() {
ReflectionTestUtils.setField(payeezyHandler,"webServiceClient",client);
Mockito.when(client.resource(anyString())).thenReturn(webResource);
Mockito.when(webResource.getRequestBuilder()).thenReturn(builder);

Mockito.when(builder.type(MediaType.APPLICATION_JSON_TYPE)).thenReturn(builder);
Mockito.when(builder.accept(MediaType.APPLICATION_JSON_TYPE)).thenReturn(builder);
Mockito.when(builder.post(Matchers.eq(String.class),anyString())).thenReturn(fakeResponse());
}

这些是最新版本,但早期版本也可以


1
投票

这是我用来嘲笑它的方式

qazxswpoi

我知道ReflectionTestUtils不好用。但是如果你的测试类只有一个公共函数来测试,那么我猜没有任何伤害。

© www.soinside.com 2019 - 2024. All rights reserved.