gpt4 book ai didi

java - 如何在JUnit中的@Rule中使用@Values字段?

转载 作者:行者123 更新时间:2023-11-30 05:35:43 32 4
gpt4 key购买 nike

如何在 junit @Rule 定义中使用 @Value spring 注入(inject)属性?

背景:我想使用 FakeSftpServerRule 创建一个带有嵌入式内存 sftp 服务器的 junit 测试。

问题:在注入(inject) @Value 字段之前执行 @Rule

@Value("${ftp.port}")
private Integer port;

@Value("${ftp.user}")
private String user;

@Value("${ftp.pass}")
private String pass;

@Rule
public final FakeSftpServerRule sftpServer = new FakeSftpServerRule().setPort(port).addUser(user, pass);

最佳答案

解决您的问题的一个解决方案是初始化 Spring 上下文并自行查找属性,如我最初的评论和 referencing to a sample 所示。这说明了这个概念。

现在的问题是,如果您不小心,您可能最终会初始化 Spring 上下文两次,一次使用静态定义,一次使用常规 Spring 测试设置。

幸运的是,Spring 本身带有 AbstractJUnit4SpringContextTests支持类,允许您重用已加载的 Spring ApplicationContext。

我们现在可以利用此功能来初始化假 SFTP 服务器,而且还允许将 Bean 注入(inject)到测试代码中,而无需通过 context.getBean(...) 调用进行手动查找。

下面的代码应该可以让您了解如何做到这一点:

@ContextConfiguration(classes = SpringTest.Config.class)
public class SpringTest extends AbstractJUnit4SpringContextTests {

@Configuration
@PropertySource("classpath:some.properties")
static class Config {
@Bean(name = "namedBean")
String someBean() {
return "Test";
}

@Bean
UUID uuidGenerator() {
return UUID.randomUUID();
}
}

static ApplicationContext context;
static int port;
static String user;
static String pass;

static {
context = new AnnotationConfigApplicationContext(SpringTest.Config.class);
Environment env = context.getBean(Environment.class);
String sPort = env.getProperty("port");
port = Integer.parseInt(sPort);
user = env.getProperty("user");
pass = env.getProperty("pass");
}

@Autowired
private UUID uuidGenerator;

public SpringTest() {
// reuse the already initialized Spring application context
setApplicationContext(context);
}

@Rule
public final FakeSftpServerRule sftpServer =
new FakeSftpServerRule().setPort(port).addUser(user, pass);

@Test
public void test() {
String someBean = context.getBean("namedBean", String.class);
System.out.println(someBean);

System.out.println(uuidGenearator.toString());
System.out.println(sftpServer.getPort());
}
}

一个可能更优雅的方法是在 Spring 配置上定义这样的东西:

@Configuration
@PropertySource("classpath:some.properties")
@EnableConfigurationProperties(SftpSettings.class)
static class Config {
...
}

其中SftpSettings是一个简单的bean类,例如

@Validated
@Getter
@Setter
@ConfigurationProperties(prefix="sftp")
public class SftpSettings {
@NotNull
private int port;
@NotNull
private String user;
@NotNull
private String pass;
}

然后在 SftpSettings 而不是 Environment 上执行查找:

static {
context = new AnnotationConfigApplicationContext(SpringTest.Config.class);
SftpSettings settings = context.getBean(SftpSettings.class);
port = settings.getPort();
user = settings.getUser();
pass = settings.getPass();
}

这样 Spring 将负责从属性文件中查找值并将这些值转换为适当的格式。

关于java - 如何在JUnit中的@Rule中使用@Values字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56667148/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com