使用Spring LDAP嵌入式服务器运行测试时出现“地址已在使用中”

dldeef67  于 2022-11-23  发布在  Spring
关注(0)|答案(6)|浏览(219)

我试图在我的一个Spring Boot项目中使用Spring LDAP,但是在运行多个测试时,我收到了"Address already in use"错误。
我在本地克隆了示例项目,如下所示:https://spring.io/guides/gs/authenticating-ldap/
...并添加了通常由Spring Boot创建的样板测试,以验证应用程序上下文是否正确加载:

@RunWith(SpringRunner.class)
@SpringBootTest
public class MyApplicationTests {
    @Test
    public void contextLoads() {
    }
}

如果单独运行,此测试通过。一旦LdapAuthenticationTests和MyApplicationTests一起运行,我就得到上面的错误。
经过一段时间的调试,我发现发生这种情况的原因是系统试图产生嵌入式服务器的第二个示例。
我确信我在配置中遗漏了一些非常愚蠢的东西。我该如何修复这个问题?

6pp0gazn

6pp0gazn1#

我遇到了类似的问题,看起来你配置了一个静态端口(就像我的情况一样)。
根据this article
SpringBoot为每个应用程序上下文启动一个嵌入式LDAP服务器。从逻辑上讲,这意味着它为每个测试类启动一个嵌入式LDAP服务器。实际上,这并不总是正确的,因为SpringBoot缓存并重用应用程序上下文。但是,您应该总是期望在执行您的测试时有多个LDAP服务器在运行。因此,您不能为您的LDAP服务器声明端口。这样,它将自动使用一个空闲端口。否则,您的测试将失败,并显示"地址已在使用"
因此,最好不要定义spring.ldap.embedded.port

e4yzc0pl

e4yzc0pl2#

我解决了同样的问题。我用一个额外的TestExecutionListener解决了它,因为你可以得到InMemoryDirectoryServer bean。

/**
 * @author slemoine
 */
public class LdapExecutionListener implements TestExecutionListener {

    @Override
    public void afterTestClass(TestContext testContext) {
        InMemoryDirectoryServer ldapServer = testContext.getApplicationContext().getBean(InMemoryDirectoryServer.class);
        ldapServer.shutDown(true);
    }
}

并且在每个SpringBootTest上(或者在一个抽象超类中只出现一次)

@RunWith(SpringRunner.class)
@SpringBootTest
@TestExecutionListeners(listeners = LdapExecutionListener.class,
        mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS)
public class MyTestClass {

...

}

也别忘了

mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS

以避免禁用整个@SpringBootTest自动配置。

dnph8jn4

dnph8jn43#

好了,我想我找到了一个解决方案,就是在我的测试类中添加一个@DirtiesContext注解:
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)

yeotifhr

yeotifhr4#

如果您正在使用spring嵌入式ldap,请尝试注解或从配置文件中删除端口值,如下所示:

spring :
  ldap:
    embedded:
      base-dn: dc=example,dc=org
      credential:
        username: cn=admin,dc=example,dc=org
        password: admin
      ldif: classpath:test-schema.ldif
      # port: 12345
      validation:
        enabled: false
fivyi3re

fivyi3re5#

尝试指定Web环境类型和基本配置类(上面带有! SpringBootApplication的类)。

@RunWith(SpringRunner.class)
@SpringBootTest(
    classes = MyApplication.class,
    webEnvironment = RANDOM_PORT
)
public class MyApplicationTests {
    @Test
    public void contextLoads() {
    }
}

为所有测试类执行此操作。

fykwrbwg

fykwrbwg6#

我通过在每个需要嵌入式ldap服务器的测试类上添加@DirtiesContext来解决这个问题。在我的例子中(和我在许多其他例子中的感觉一样),嵌入式ldap服务器在每个@SpringBootTest时启动,因为我将所有spring.ldap.embedded.* 属性添加到通用应用程序-test.properties中。因此,当我运行一系列测试时,“Address already in use”的问题破坏了所有测试的通过。
我遵循的步骤:

  • 创建一个附加的测试配置文件(使用相应的命名应用程序属性文件,例如“application-ldaptest.properties”)
  • 将所有spring.ldap.embedded.* 属性(具有固定端口值)移到该文件
  • 在所有需要运行嵌入式服务器的@SpringBootTest-s上,添加@ActiveProfiles(“testlapp”)和@DirtiesContext注解。

希望,这有帮助。

相关问题