我在运行 Junit 测试时遇到问题,该测试使用标记为 @Configurable 的类。可配置标记 bean 自动装配字段不会注入并保持为 Null。
我提供了重现该问题的代码示例项目代码:
SomeDependency.class
package com.codeslab;
import org.springframework.stereotype.Service;
@Service
public class SomeDependency {
public String doSomethingInSomeDependency() {
return "doSomethingInSomeDependency";
}
}
SomeService.class
package com.codeslab;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
@Configurable
public class SomeService {
@Autowired
private SomeDependency mSomeDependency;
public String doSomething() {
return mSomeDependency.doSomethingInSomeDependency();
}
}
测试代码: SomeTest-Context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<context:annotation-config/>
<!-- Enable Spring AspectJ support -->
<context:spring-configured/>
<!-- Enable AspectJ auto proxying -->
<aop:aspectj-autoproxy/>
<bean class="com.codeslab.SomeDependency"/>
</beans>
SomeTest.class
package com.codeslab;
import org.junit.jupiter.api.*;
import org.junit.jupiter.api.extension.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ContextConfiguration(locations = { "/SomeTest-Context.xml" })
@ExtendWith(SpringExtension.class)
public class SomeTest {
final SomeService mMyService = new SomeService();
@Autowired
private SomeDependency mSomeDependency;
@Test
public void test() {
Assertions.assertNotNull(mSomeDependency);
final String something = mMyService.doSomething();
Assertions.assertEquals("doSomethingInSomeDependency", something);
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.codes-lab</groupId>
<artifactId>spring-autoproxy</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<aspectjweaver.version>1.9.22.1</aspectjweaver.version>
<spring.version>6.1.13</spring.version>
<junit.version>5.10.3</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Spring Aspects -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
</project>
我尝试用上面的示例代码重现该问题。我已经在上下文中使用了 aop:aspectj-autoproxy/ 。我试图遵循 Spring-aop-可配置测试
但我仍然得到 NPE: java.lang.NullPointerException:无法调用“com.codeslab.SomeDependency.doSomethingInSomeDependency()”,因为“this.mSomeDependency”为空
at com.codeslab.SomeService.doSomething(SomeService.java:23)
at com.codeslab.SomeTest.test(SomeTest.java:32)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
aop:aspectj-autoproxy/ 不应该负责将 Somedependency 注入 SomeService 吗?我在这里遗漏或忽略了什么?
编辑:我更喜欢编译时编织。
请在所有位置将变量重命名为 someDependency 或使用 @qualifier 给出您选择的名称。
@Autowired
private SomeDependency mSomeDependency;