Spring 在 Groovy 测试期间自动装配 bean NullPointerException 但在运行时工作正常
Spring Autowire bean NullPointerException during Groovy tests but works fine during Runtime
我正在使用 prometheus 库来获取我的 Spring 引导应用程序 (REST API) 的指标。我正在使用库 io.prometheus.simpleclient:0.4.0
并将其包含在我的 Maven pom.xml 中。我正在使用 Counter
和 @Autowiring(我已经尝试过字段和构造函数注入)它到我自己的 classes 之一,就像这样
MyCustomMetricsClass.java
@Component
public MyCustomMetricsClass {
@Autowire
private Counter counterBean;
public void myOwnMetricsMethod() {
counterBean.inc();
// do some stuff
}
THEN,我@Autowiring这个MyCustomMetricsClass
进入我的服务class,MyServiceClass.java
,当我 运行 我的 API 在本地使用 Spring Boot embedded tomcat 在端口 8080 (localhost:8080) 时,它似乎 运行 很好。我可以命中端点,并且在执行器端点 (localhost:8080/actuator/metrics) 正确报告指标。例如
MyServiceClass.java
public MyServiceClass {
@Autowire
private MyCustomMetricsclass myMetrics;
public void genericServiceMethod() {
myMetrics.MyOwnMetricsMethod(); // NULL POINTER EXCEPTION ONLY DURING TEST SCOPE (GROOVY)
}
问题是,当我 运行 mvn install
触发我编写的本地 Groovy 单元测试时,我不断收到 NULL POINTER EXCEPTION。使用调试器,我可以调试 Groovy 单元测试并在我的服务 class 中看到 myMetrics
变量为 NULL。但是我不明白为什么它在 运行 时可以正常工作,另外,我将 MyCustomMetricsClass
注释为 @Component 注释,所以它应该是bean 正在被 Spring 组件扫描扫描。
这是一个多模块项目;结构如下
my-project (root, contains root pom.xml)
- my-api (module, contains RestController. has its own pom.xml)
- my-service (module. contains service classes, has its own pom.xml)
- my-model (module, contains all POJO/DTO model classes, has its own pom.xml)
我是否遗漏了对 class 路径的依赖?为什么它在 运行 时间起作用,但在测试期间不起作用? (我所有的依赖项都应该有默认范围)自动装配是否损坏?
你能分享你的单元测试代码吗?
我猜,您使用的是模拟框架,也许是 Mockito?
如果这个假设成立,请记住,您的单元测试不会 运行 完整 Spring 上下文,因此不会发生自动连接。您将需要为自动装配的组件注入模拟。
例如:
@RunWith(MockitoJUnitRunner.class)
public class MyServiceClassTest {
@Mock
private MyCustomMetricsClass myCustomMetricsClass;
@InjectMocks
private MyServiceClass myServiceClass;
@Test
public void shouldDoTesting() {
myServiceClass. genericServiceMethod();
verify(myMetrics).MyOwnMetricsMethod();
}
}
我正在使用 prometheus 库来获取我的 Spring 引导应用程序 (REST API) 的指标。我正在使用库 io.prometheus.simpleclient:0.4.0
并将其包含在我的 Maven pom.xml 中。我正在使用 Counter
和 @Autowiring(我已经尝试过字段和构造函数注入)它到我自己的 classes 之一,就像这样
MyCustomMetricsClass.java
@Component
public MyCustomMetricsClass {
@Autowire
private Counter counterBean;
public void myOwnMetricsMethod() {
counterBean.inc();
// do some stuff
}
THEN,我@Autowiring这个MyCustomMetricsClass
进入我的服务class,MyServiceClass.java
,当我 运行 我的 API 在本地使用 Spring Boot embedded tomcat 在端口 8080 (localhost:8080) 时,它似乎 运行 很好。我可以命中端点,并且在执行器端点 (localhost:8080/actuator/metrics) 正确报告指标。例如
MyServiceClass.java
public MyServiceClass {
@Autowire
private MyCustomMetricsclass myMetrics;
public void genericServiceMethod() {
myMetrics.MyOwnMetricsMethod(); // NULL POINTER EXCEPTION ONLY DURING TEST SCOPE (GROOVY)
}
问题是,当我 运行 mvn install
触发我编写的本地 Groovy 单元测试时,我不断收到 NULL POINTER EXCEPTION。使用调试器,我可以调试 Groovy 单元测试并在我的服务 class 中看到 myMetrics
变量为 NULL。但是我不明白为什么它在 运行 时可以正常工作,另外,我将 MyCustomMetricsClass
注释为 @Component 注释,所以它应该是bean 正在被 Spring 组件扫描扫描。
这是一个多模块项目;结构如下
my-project (root, contains root pom.xml)
- my-api (module, contains RestController. has its own pom.xml)
- my-service (module. contains service classes, has its own pom.xml)
- my-model (module, contains all POJO/DTO model classes, has its own pom.xml)
我是否遗漏了对 class 路径的依赖?为什么它在 运行 时间起作用,但在测试期间不起作用? (我所有的依赖项都应该有默认范围)自动装配是否损坏?
你能分享你的单元测试代码吗?
我猜,您使用的是模拟框架,也许是 Mockito?
如果这个假设成立,请记住,您的单元测试不会 运行 完整 Spring 上下文,因此不会发生自动连接。您将需要为自动装配的组件注入模拟。
例如:
@RunWith(MockitoJUnitRunner.class)
public class MyServiceClassTest {
@Mock
private MyCustomMetricsClass myCustomMetricsClass;
@InjectMocks
private MyServiceClass myServiceClass;
@Test
public void shouldDoTesting() {
myServiceClass. genericServiceMethod();
verify(myMetrics).MyOwnMetricsMethod();
}
}