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

Zap*_*rox 5 testing spring-ldap unboundid-ldap-sdk spring-boot

我试图在我的一个Spring Boot项目中使用Spring LDAP,但是运行多个测试时出现“ Address in use”错误。

我已经在这里本地克隆了示例项目:https : //spring.io/guides/gs/authenticating-ldap/

...并刚刚添加了通常由Spring Boot创建的样板测试,以验证Application Context是否正确加载:

@RunWith(SpringRunner.class)
@SpringBootTest
public class MyApplicationTests {
    @Test
    public void contextLoads() {
    }
}
Run Code Online (Sandbox Code Playgroud)

如果单独运行,则此测试通过。一旦LdapAuthenticationTests和MyApplicationTests一起运行,我会得到上面关于后者的错误。

经过一番调试后,我发现发生这种情况是因为系统尝试生成嵌入式服务器的第二个实例。

我确定我在配置中缺少一些非常愚蠢的东西。我该如何解决这个问题?

Wal*_*rer 7

我有一个类似的问题,看起来你配置了一个静态端口(就像我的情况一样)。

根据这篇文章

Spring Boot 为每个应用程序上下文启动一个嵌入式 LDAP 服务器。从逻辑上讲,这意味着它为每个测试类启动一个嵌入式 LDAP 服务器。实际上,这并不总是正确的,因为 Spring Boot 缓存和重用应用程序上下文。但是,您应该始终期望在执行测试时有多个 LDAP 服务器在运行。因此,您不能为 LDAP 服务器声明端口。这样,它就会自动使用一个空闲端口。否则,您的测试将失败并显示“地址已在使用中”

因此,根本不定义可能是一个更好的主意spring.ldap.embedded.port


sle*_*ine 7

我解决了同样的问题。我用一个额外的 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

并在每个 SpringBootTest 上(或仅在抽象超类中一次)

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

...

}
Run Code Online (Sandbox Code Playgroud)

也不要忘记

mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS
Run Code Online (Sandbox Code Playgroud)

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


Pyt*_*try 0

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

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

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