Spring 为什么随机_端口不可分配?
我有一些带有硬编码url baseUrl=http://localhost:8080/api/v1/. 当我尝试将其交换为baseUrl=http://localhost: +端口+/api/v1/,我得到 这里的问题是什么Spring 为什么随机_端口不可分配?,spring,spring-mvc,spring-test,Spring,Spring Mvc,Spring Test,我有一些带有硬编码url baseUrl=http://localhost:8080/api/v1/. 当我尝试将其交换为baseUrl=http://localhost: +端口+/api/v1/,我得到 这里的问题是什么 @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class UrlShorteningControllerTest { @Autowired private TestRestTemp
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class UrlShorteningControllerTest {
@Autowired
private TestRestTemplate restTemplate;
@LocalServerPort
private int port;
private String baseUrl = "http://localhost:" + port + "/api/v1/";
// private String baseUrl = "http://localhost:8080/api/v1/"; // THIS WORKS FINE
@Test
void findAndRedirectHappyPath() throws URISyntaxException {
final String dishpodUrl = baseUrl + "dishpods";
URI uri = new URI(dishpodUrl);
ResponseEntity<String> result = this.restTemplate.getForEntity(uri, String.class);
assertEquals(302, result.getStatusCodeValue());
assertTrue(result.toString().contains("amazon.com"));
}
堆栈跟踪
I/O error on GET request for "http://localhost:0/api/v1/dishpods": Can't assign requested address (Address not available); nested exception is java.net.NoRouteToHostException: Can't assign requested address (Address not available)
org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://localhost:0/api/v1/dishpods": Can't assign requested address (Address not available); nested exception is java.net.NoRouteToHostException: Can't assign requested address (Address not available)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:748)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:714)
at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:358)
at org.springframework.boot.test.web.client.TestRestTemplate.getForEntity(TestRestTemplate.java:265)
at com.example.urlshortener.api.UrlShorteningControllerTest.findAndRedirectHappyPath(UrlShorteningControllerTest.java:111)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:686)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:212)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:208)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:137)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:71)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:132)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
at com.sun.proxy.$Proxy2.stop(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:132)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:413)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.net.NoRouteToHostException: Can't assign requested address (Address not available)
at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:399)
at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:242)
at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:224)
at java.base/java.net.Socket.connect(Socket.java:609)
at java.base/java.net.Socket.connect(Socket.java:558)
at java.base/sun.net.NetworkClient.doConnect(NetworkClient.java:182)
at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:474)
at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:569)
at java.base/sun.net.www.http.HttpClient.<init>(HttpClient.java:242)
at java.base/sun.net.www.http.HttpClient.New(HttpClient.java:341)
at java.base/sun.net.www.http.HttpClient.New(HttpClient.java:362)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1248)
at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1187)
at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1081)
at java.base/sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:1015)
at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:76)
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:739)
... 92 more
您正在类初始化中执行代码,因此字符串不能修改已经计算的字符串 这一行:
private String baseUrl = "http://localhost:" + port + "/api/v1/";
不会工作,因为Spring没有完成注入工作,所以“port”变量仍然等于零
此操作必须在以下位置完成:
@Test
void findAndRedirectHappyPath() throws URISyntaxException {
String baseUrl = "http://localhost:" + port + "/api/v1/";
// the rest of your test
}
或者像这样的东西可以很好地工作:
private String baseUrl;
@PostConstruct
private void postConstruct() {
baseUrl = "http://localhost:" + port + "/api/v1/";
}
您正在类初始化中执行代码,因此字符串不能修改已经计算的字符串 这一行:
private String baseUrl = "http://localhost:" + port + "/api/v1/";
不会工作,因为Spring没有完成注入工作,所以“port”变量仍然等于零
此操作必须在以下位置完成:
@Test
void findAndRedirectHappyPath() throws URISyntaxException {
String baseUrl = "http://localhost:" + port + "/api/v1/";
// the rest of your test
}
或者像这样的东西可以很好地工作:
private String baseUrl;
@PostConstruct
private void postConstruct() {
baseUrl = "http://localhost:" + port + "/api/v1/";
}
目前发生的情况:
Spring使用默认构造函数创建UrlShorteningControllerTest
创建的UrlShortEngingController测试对象具有以下值
restTemplate=对象的默认值为空
端口=0 int的默认值
baseUrl=http://localhost:0/api/v1/
Spring注入自动连线依赖项
restTemplate=某个对象
端口-选择的端口
baseUrl-不会更改,因为它不是自动关联的依赖项
解决方案:
我假设您有许多测试方法,并且希望在字段级别设置基本url
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class UrlShorteningControllerTest {
@Autowired
private TestRestTemplate restTemplate;
@LocalServerPort
private int port;
private String baseUrl;
@PostConstruct
public void initialise(){
baseUrl = "http://localhost:" + port + "/api/v1/";
}
背景:
查看bean的生命周期
参考:
目前发生的情况:
Spring使用默认构造函数创建UrlShorteningControllerTest
创建的UrlShortEngingController测试对象具有以下值
restTemplate=对象的默认值为空
端口=0 int的默认值
baseUrl=http://localhost:0/api/v1/
Spring注入自动连线依赖项
restTemplate=某个对象
端口-选择的端口
baseUrl-不会更改,因为它不是自动关联的依赖项
解决方案:
我假设您有许多测试方法,并且希望在字段级别设置基本url
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class UrlShorteningControllerTest {
@Autowired
private TestRestTemplate restTemplate;
@LocalServerPort
private int port;
private String baseUrl;
@PostConstruct
public void initialise(){
baseUrl = "http://localhost:" + port + "/api/v1/";
}
背景:
查看bean的生命周期
参考:
您试图通过计算要调用的整个URL来智取Spring Boot TestRestTemplate。您不需要这样做,因为TestRestTemplate本身就可以这样做。只需向/api/v1发出一个请求,让测试支持完成其余的工作
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class UrlShorteningControllerTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
void findAndRedirectHappyPath() throws URISyntaxException {
ResponseEntity<String> result = this.restTemplate.getForEntity("/api/v1", String.class);
assertEquals(302, result.getStatusCodeValue());
assertTrue(result.toString().contains("amazon.com"));
}
}
这就是运行测试所需的全部内容。您试图通过计算要调用的整个URL来智胜Spring Boot TestRestTemplate。您不需要这样做,因为TestRestTemplate本身就可以这样做。只需向/api/v1发出一个请求,让测试支持完成其余的工作
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class UrlShorteningControllerTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
void findAndRedirectHappyPath() throws URISyntaxException {
ResponseEntity<String> result = this.restTemplate.getForEntity("/api/v1", String.class);
assertEquals(302, result.getStatusCodeValue());
assertTrue(result.toString().contains("amazon.com"));
}
}
这就是运行测试所需的全部内容。删除URL处理。只需向/api/v1发出请求。TestRestTEmplate将根据配置确定剩余部分。删除URL处理。只需向/api/v1发出请求。TestRestTEmplate将根据配置确定剩余部分。