在尝试解决Where exactly is the NullPointer Exception?中描述的测试时,我使用了一种看似简单的方法,作为下一步的资源测试:
public class CustomerResourceFunctionalTesting {
private static final String SERVER_URL = "http://localhost:8080/api/v0/";
@Rule
public ExpectedException thrown = ExpectedException.none();
private int createCustomer(String name) {
CustomerDto customerDto = new CustomerDto(name, name + " address");
return new RestBuilder2<Integer>(SERVER_URL).path(CustomerResource.CUSTOMERS)
.body(customerDto).clazz(Integer.class).post().build();
}
private int createCustomer() {
return this.createCustomer("customer1");
}
@Test
public void testReadCustomers() {
List<CustomerDto> customerDtoList = Arrays.asList(new RestBuilder2<CustomerDto[]>
(SERVER_URL).path(CustomerResource.CUSTOMERS).clazz(CustomerDto[].class).get().build());
assertEquals(0, customerDtoList.size());
int id = this.createCustomer();
customerDtoList = Arrays.asList(new RestBuilder2<CustomerDto[]>
(SERVER_URL).path(CustomerResource.CUSTOMERS).clazz(CustomerDto[].class)
.get().build());
assertEquals(1, customerDtoList.size());
this.deleteCustomer(id);
}
private void deleteCustomer(int id) {
new RestBuilder<Object>
(SERVER_URL).path(CustomerResource.CUSTOMERS).path(CustomerResource.CUSTOMER_ID)
.expand(id).delete().build();
}
}
RestBuilder有点不同:
public class RestBuilder2<T> {
private RestTemplate restTemplate = new RestTemplate();
private String uri;
private List<Object> expandList;
private Map<String, String> headerValues;
private String authorization = null;
private Object body = null;
private MultiValueMap<String, String> params;
private Class<T> clazz;
private HttpMethod method;
public RestBuilder2(String serverUri) {
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
this.uri = serverUri;
this.expandList = new ArrayList<>();
headerValues = new HashMap<>();
params = new HttpHeaders();
}
public RestBuilder2<T> path(String path) {
this.uri = this.uri + path;
return this;
}
public RestBuilder2<T> expand(Object... values) {
for (Object value : values) {
this.expandList.add(value);
}
return this;
}
public RestBuilder2<T> pathId(int path) {
this.uri = this.uri + "/" + path;
return this;
}
public RestBuilder2<T> pathId(String path) {
this.uri = this.uri + "/" + path;
return this;
}
public RestBuilder2<T> authorization(String authorizationValue) {
this.authorization = authorizationValue;
return this;
}
public RestBuilder2<T> basicAuth(String nick, String pass) {
String auth = nick + ":" + pass;
String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes(StandardCharsets.UTF_8));
String authHeader = "Basic " + encodedAuth;
this.authorization = authHeader;
return this;
}
public RestBuilder2<T> param(String key, String value) {
this.params.add(key, value);
return this;
}
public RestBuilder2<T> header(String key, String value) {
this.headerValues.put(key, value);
return this;
}
public RestBuilder2<T> body(Object body) {
this.body = body;
return this;
}
public RestBuilder2<T> notError() {
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
protected boolean hasError(HttpStatus statusCode) {
return false;
}
});
return this;
}
public RestBuilder2<T> clazz(Class<T> clazz) {
this.clazz = clazz;
return this;
}
private HttpHeaders headers() {
HttpHeaders headers = new HttpHeaders();
for (String key : headerValues.keySet()) {
headers.set(key, headerValues.get(key));
}
if (authorization != null) {
headers.set("Authorization", authorization);
}
return headers;
}
private URI uri() {
UriComponents uriComponents;
if (params.isEmpty()) {
uriComponents = UriComponentsBuilder.fromHttpUrl(uri).build();
} else {
uriComponents = UriComponentsBuilder.fromHttpUrl(uri).queryParams(params).build();
}
if (!expandList.isEmpty()) {
uriComponents = uriComponents.expand(expandList.toArray());
}
return uriComponents.encode().toUri();
}
public T build() {
if (body != null && !method.equals(HttpMethod.GET)) {
return restTemplate.exchange(this.uri(), method, new HttpEntity<Object>(body, this.headers()), clazz).getBody();
} else {
return restTemplate.exchange(this.uri(), method, new HttpEntity<Object>(this.headers()), clazz).getBody();
}
}
public RestBuilder2<T> post() {
this.method = HttpMethod.POST;
return this;
}
public RestBuilder2<T> get() {
this.method = HttpMethod.GET;
return this;
}
public RestBuilder2<T> put() {
this.method = HttpMethod.PUT;
return this;
}
public RestBuilder2<T> patch() {
this.method = HttpMethod.PATCH;
return this;
}
public RestBuilder2<T> delete() {
this.method = HttpMethod.DELETE;
return this;
}
}
但是我接受了一个错误,其痕迹是:
org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://localhost:8080/api/v0/customers": Connect to localhost:8080 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect; nested exception is org.apache.http.conn.HttpHostConnectException: Connect to localhost:8080 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:674)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:636)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:557)
at account.persistence.resources.RestBuilder2.build(RestBuilder2.java:143)
at account.persistence.resources.CustomerResource2FunctionalTesting.testReadCustomers(CustomerResource2FunctionalTesting.java:34)
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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:239)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
Caused by: org.apache.http.conn.HttpHostConnectException: Connect to localhost:8080 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect
at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:159)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:373)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:381)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:237)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:111)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:89)
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:660)
... 29 more
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
除了不使用任何RestService之外,应用程序的其余隐含部分与链接帖中指示的部分相同。
我认为,在这种情况下,我无法获得NullPointerException,但在我需要解决ResourceAccess异常之前。