Java - 构造函数单元测试
Java - Constructor Unit testing
我有以下 Java 配置 class 我需要使用 JUnit 进行单元测试:
public class Config {
private static final String AMQ_CONNECTION_URL_TEMPLATE = "failover:(%s)";
private final String awsAmqUrl;
public Config(String url, Optional<String> amqConnectionOptions, PropertiesManager propertiesManager) {
String urlParameter = propertiesManager.getStringParameter(url);
this.awsAmqUrl = constructAmqConnectionString(urlParameter, amqConnectionOptions);
}
private String constructAmqConnectionString(String urlParameter, Optional<String> connectionOptions) {
if (connectionOptions.isPresent()) {
urlParameter = Stream.of(urlParameter.split(","))
.map(url -> url + "?" + connectionOptions.get())
.collect(Collectors.joining(","));
}
return String.format(AMQ_CONNECTION_URL_TEMPLATE, urlParameter);
}
public ConnectionFactory getConnectionFactory() {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(awsAmqUrl);
return connectionFactory;
}
}
我正在努力寻找 constructAmqConnectionString
方法单元测试的最佳解决方案,因为它被标记为私有。
我试图涵盖 3 种情况:
urlParameter
- 包含逗号分隔的 URLs (url1,url2),
connectionOptions
不为空;
urlParameter
- 包含逗号
分隔URLs(url1,url2),connectionOptions
为空;
urlParameter
- 包含单个 URL (url1),connectionOptions
是
不为空。
目前的解决方案是在Config class中为awsAmqUrl
字段添加一个getter,这样构造函数的调用逻辑就可以是verified/tested:
public String getAwsAmqUrl() {
return this.awsAmqUrl;
}
测试本身具有以下逻辑:
@Test
public void verifyConstructorWithoutMqOptionsMultiBroker() {
when(propertiesManager.getStringParameter(any())).thenReturn("url1,url2");
Optional<String> amqConnectionOptions = Optional.empty();
config = new Config("url1,url2", amqConnectionOptions, propertiesManager);
assertEquals(String.format("failover:(url1,url2)"),config.getAwsAmqUrl());
}
@Test
public void verifyConstructorWithMqOptionsMultiBroker() {
when(propertiesManager.getStringParameter(any())).thenReturn("url1,url2");
Optional<String> amqConnectionOptions = Optional.of("optionTest=1");
config = new Config("url1,url2", amqConnectionOptions, propertiesManager);
assertEquals(String.format("failover:(url1?%1$s,url2?%1$s)",amqConnectionOptions.get()),config.getAwsAmqUrl());
}
@Test
public void verifyConstructorWithMqOptionsSingleBroker() {
when(propertiesManager.getStringParameter(any())).thenReturn("url1");
Optional<String> amqConnectionOptions = Optional.of("optionTest=1");
config = new Config("url1", amqConnectionOptions, propertiesManager);
assertEquals(String.format("failover:(url1?%1$s)",amqConnectionOptions.get()),config.getAwsAmqUrl());
}
仅出于单元测试目的添加 getter 感觉不对,因为它破坏了封装。
在这种情况下是否有更好的方法来进行测试?
您的 class 使用 awsAmqUrl
的唯一地方是在 getConnectionFactory
方法中。所以看起来这是您必须使用的方法,以确保 awsAmqUrl
的值是正确的。因此,不要为 awsAmqUrl
使用 getter,而是使用类似
的东西
String storedUrl = objectUnderTest.getConnectionFactory().getBrokerUrl();
然后你可以对 URL 做出断言。
当然,它使您的测试依赖于 ActiveMQConnectionFactory
的行为 - 但没关系,因为您的 class 无论如何都与特定的 class 紧密耦合。
我有以下 Java 配置 class 我需要使用 JUnit 进行单元测试:
public class Config {
private static final String AMQ_CONNECTION_URL_TEMPLATE = "failover:(%s)";
private final String awsAmqUrl;
public Config(String url, Optional<String> amqConnectionOptions, PropertiesManager propertiesManager) {
String urlParameter = propertiesManager.getStringParameter(url);
this.awsAmqUrl = constructAmqConnectionString(urlParameter, amqConnectionOptions);
}
private String constructAmqConnectionString(String urlParameter, Optional<String> connectionOptions) {
if (connectionOptions.isPresent()) {
urlParameter = Stream.of(urlParameter.split(","))
.map(url -> url + "?" + connectionOptions.get())
.collect(Collectors.joining(","));
}
return String.format(AMQ_CONNECTION_URL_TEMPLATE, urlParameter);
}
public ConnectionFactory getConnectionFactory() {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(awsAmqUrl);
return connectionFactory;
}
}
我正在努力寻找 constructAmqConnectionString
方法单元测试的最佳解决方案,因为它被标记为私有。
我试图涵盖 3 种情况:
urlParameter
- 包含逗号分隔的 URLs (url1,url2),connectionOptions
不为空;urlParameter
- 包含逗号 分隔URLs(url1,url2),connectionOptions
为空;urlParameter
- 包含单个 URL (url1),connectionOptions
是 不为空。
目前的解决方案是在Config class中为awsAmqUrl
字段添加一个getter,这样构造函数的调用逻辑就可以是verified/tested:
public String getAwsAmqUrl() {
return this.awsAmqUrl;
}
测试本身具有以下逻辑:
@Test
public void verifyConstructorWithoutMqOptionsMultiBroker() {
when(propertiesManager.getStringParameter(any())).thenReturn("url1,url2");
Optional<String> amqConnectionOptions = Optional.empty();
config = new Config("url1,url2", amqConnectionOptions, propertiesManager);
assertEquals(String.format("failover:(url1,url2)"),config.getAwsAmqUrl());
}
@Test
public void verifyConstructorWithMqOptionsMultiBroker() {
when(propertiesManager.getStringParameter(any())).thenReturn("url1,url2");
Optional<String> amqConnectionOptions = Optional.of("optionTest=1");
config = new Config("url1,url2", amqConnectionOptions, propertiesManager);
assertEquals(String.format("failover:(url1?%1$s,url2?%1$s)",amqConnectionOptions.get()),config.getAwsAmqUrl());
}
@Test
public void verifyConstructorWithMqOptionsSingleBroker() {
when(propertiesManager.getStringParameter(any())).thenReturn("url1");
Optional<String> amqConnectionOptions = Optional.of("optionTest=1");
config = new Config("url1", amqConnectionOptions, propertiesManager);
assertEquals(String.format("failover:(url1?%1$s)",amqConnectionOptions.get()),config.getAwsAmqUrl());
}
仅出于单元测试目的添加 getter 感觉不对,因为它破坏了封装。 在这种情况下是否有更好的方法来进行测试?
您的 class 使用 awsAmqUrl
的唯一地方是在 getConnectionFactory
方法中。所以看起来这是您必须使用的方法,以确保 awsAmqUrl
的值是正确的。因此,不要为 awsAmqUrl
使用 getter,而是使用类似
String storedUrl = objectUnderTest.getConnectionFactory().getBrokerUrl();
然后你可以对 URL 做出断言。
当然,它使您的测试依赖于 ActiveMQConnectionFactory
的行为 - 但没关系,因为您的 class 无论如何都与特定的 class 紧密耦合。