java - @Value 在单元测试中返回 null
问题描述
我有一个带有端点测试配置类和单元测试的 spring boot 应用程序来测试我的 http 客户端。我正在尝试从位于我的 src/test 中的 application.properties 获取我的服务器地址和端口。(所有类都在我的 src/test 中。)
这是我的配置类代码:
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import javax.xml.bind.JAXBException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ResourceUtils;
import com.nulogix.billing.service.PredictionEngineService;
import com.nulogix.billing.ws.endpoint.AnalyzeEndPoint;
import com.nulogix.billing.ws.endpoint.GetVersionEndPoint;
@Configuration
public class EndPointTestConfiguration {
@Value("${billing.engine.address}")
private String mockAddress;
@Value("${billing.engine.port}")
private String mockPort;
@Bean
public String getAddress() {
String serverAddress = "http://" + mockAddress + ":" + mockPort;
return serverAddress;
}
@Bean
public GetVersionEndPoint getVersionEndPoint() {
return new GetVersionEndPoint();
}
我用@value 注释了我的.properties 中的值,然后创建了一个我用bean 实例化的方法以返回我的服务器地址字符串。
然后,我在 HttpClientTest 类中使用该字符串值:
import static org.junit.Assert.*;
import java.io.IOException;
import java.util.Map;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.fluent.Request;
import org.apache.http.entity.ContentType;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ConfigurableApplicationContext;
import com.google.gson.Gson;
import com.nulogix.billing.configuration.EndPointTestConfiguration;
import com.nulogix.billing.mockserver.MockServerApp;
@SpringBootTest(classes = EndPointTestConfiguration.class)
public class HttpClientTest {
@Autowired
EndPointTestConfiguration endpoint;
public static final String request_bad = "ncs|56-2629193|1972-03-28|20190218|77067|6208|3209440|self|";
public static final String request_good = "ncs|56-2629193|1972-03-28|20190218|77067|6208|3209440|self|-123|-123|-123|0.0|0.0|0.0|0.0|0.0|0.0|0.0";
//gets application context
static ConfigurableApplicationContext context;
//call mock server before class
@BeforeClass
static public void setup(){
SpringApplication springApplication = new SpringApplicationBuilder()
.sources(MockServerApp.class)
.build();
context = springApplication.run();
}
//shutdown mock server after class
@AfterClass
static public void tearDown(){
SpringApplication.exit(context);
}
@Test
public void test_bad() throws ClientProtocolException, IOException {
// missing parameter
String result = Request.Post(endpoint.getAddress())
.connectTimeout(2000)
.socketTimeout(2000)
.bodyString(request_bad, ContentType.TEXT_PLAIN)
.execute().returnContent().asString();
Map<?, ?> resultJsonObj = new Gson().fromJson(result, Map.class);
// ensure the key exists
assertEquals(resultJsonObj.containsKey("status"), true);
assertEquals(resultJsonObj.containsKey("errorMessage"), true);
// validate values
Boolean status = (Boolean) resultJsonObj.get("status");
assertEquals(status, false);
String errorMessage = (String) resultJsonObj.get("errorMessage");
assertEquals(errorMessage.contains("Payload has incorrect amount of parts"), true);
}
@Test
public void test_good() throws ClientProtocolException, IOException {
String result = Request.Post(endpoint.getAddress())
.connectTimeout(2000)
.socketTimeout(2000)
.bodyString(request_good, ContentType.TEXT_PLAIN)
.execute().returnContent().asString();
Map<?, ?> resultJsonObj = new Gson().fromJson(result, Map.class);
// ensure the key exists
assertEquals(resultJsonObj.containsKey("status"), true);
assertEquals(resultJsonObj.containsKey("errorMessage"), false);
assertEquals(resultJsonObj.containsKey("HasCopay"), true);
assertEquals(resultJsonObj.containsKey("CopayAmount"), true);
assertEquals(resultJsonObj.containsKey("HasCoinsurance"), true);
assertEquals(resultJsonObj.containsKey("CoinsuranceAmount"), true);
assertEquals(resultJsonObj.containsKey("version"), true);
// validate values
Boolean status = (Boolean) resultJsonObj.get("status");
assertEquals(status, true);
String version = (String) resultJsonObj.get("version");
assertEquals(version, "0.97");
}
}
我在 request.post 中使用它,我不想在我的 IP 地址和端口号中硬编码。
当我运行测试时,它说
[ERROR] HttpClientTest.test_bad:63 NullPointer
[ERROR] HttpClientTest.test_good:86 NullPointer
但我不确定为什么它是空的?我很确定我已经实例化了所有内容,并且字符串已经清楚地填充了..
我的配置包结构是 com.billing.mockserver,我的单元测试包结构是 com.billing.ws.endpoint。
这是我的 application.properties
server.port=9119
server.ssl.enabled=false
logging.config=classpath:logback-spring.xml
logging.file=messages
logging.file.max-size=50MB
logging.level.com.nulogix=DEBUG
billing.engine.address=127.0.0.1
billing.engine.port=9119
billing.engine.api.version=0.97
billing.engine.core.name=Patient_Responsibility
解决方案
您缺少对 springboot 的基本了解。@Configuration
class 是初始化其他 spring bean 和其他东西,并且是第一个被初始化的类。你不应该@Autowire
@configuration
上课。
在您的配置类中,您可以为用户名和密码创建 Spring bean,并在您的测试类中自动装配或直接@Value
在您的测试类中使用。
示例:在您的配置类中,您正在创建 bean,GetVersionEndPoint
您可以autowire
在 Test 类中创建它。
更新 2:
对于测试类,您需要添加application.properties
文件src\test\resource
推荐阅读
- angular - 在服务上存储持久数据(Angular 2)
- scheme - SICP 实践 3.51 申请类型错误:#
- c# - .NET Core - 构建项目指定 ReferencePath
- angularjs - uigrid 正在捕获键盘按键事件
- amcharts - 使用 amCharts 显示多个值的总和
- python - docs.python.org 与代码不同
- google-apps-script - 检查谷歌工作表中所有工作表之间的重复项
- javascript - javascript > Kendo 网格 > 动态列过滤不起作用
- apache - 配置 apache2 和 host 以使用 nginx 将流量传递到 docker 容器
- apollo-client - 如何让所有可见的 Vue 组件重新获取它们的 Apollo 查询?