JUnit4+Mockito测试中如何为Java的@Value注解设置值?
解决方案
针对你遇到的JUnit4+Mockito测试中Class2的@Value变量为null的问题,结合你的场景给出以下可行方案:
方案1:正确结合Spring上下文赋值(Class2为Spring Bean时)
如果Class2是Spring容器管理的Bean,之前用ReflectionTestUtils失效可能是没拿到容器内的真实实例。直接在Spring测试上下文里获取实例并赋值:
@SpringBootTest @TestPropertySource(locations = "classpath:application-test.properties") public class Class1Test { @Autowired private Class2 class2; @Autowired private Class1 class1; @Before public void setUp() { // 给容器内的Class2实例赋值@Value对应的字段 ReflectionTestUtils.setField(class2, "yourValueField", "配置值"); } @Test public void testTargetMethod() { class1.targetMethod(); // 后续断言或验证逻辑 } }
方案2:替换Util1中的Class2实例(Class2非Spring管理时)
如果Util1是手动new Class2()而非依赖注入,需让Util1使用我们可控的Class2实例:
方式1:修改Util1增加测试入口(允许改源码时)
给Util1加静态setter替换Class2实例:
public class Util1 { private static Class2 class2 = new Class2(); // 新增测试用静态方法 public static void setClass2(Class2 customClass2) { class2 = customClass2; } public static void targetStaticMethod() { class2.validateCondition(); } }
测试类中创建赋值后的Class2实例并替换:
public class Class1Test { @Before public void setUp() { Class2 customClass2 = new Class2(); ReflectionTestUtils.setField(customClass2, "yourValueField", "配置值"); Util1.setClass2(customClass2); } @Test public void testTargetMethod() { new Class1().targetMethod(); } }
方式2:用PowerMock拦截Class2的构造(不能改源码时)
之前用PowerMock失效大概率是没指定正确的拦截类,需拦截调用new的类(即Util1):
@RunWith(PowerMockRunner.class) @PrepareForTest(Util1.class) // 重点:要拦截的是Util1里的new操作 public class Class1Test { @Test public void testTargetMethod() throws Exception { // 创建Class2实例并赋值 Class2 class2 = new Class2(); ReflectionTestUtils.setField(class2, "yourValueField", "配置值"); // 拦截Util1中new Class2()的操作,返回我们的实例 PowerMockito.whenNew(Class2.class).withAnyArguments().thenReturn(class2); // 执行测试 new Class1().targetMethod(); } }
方案3:Mock Class2的校验逻辑(无需真实校验时)
如果不需要执行Class2的真实校验逻辑,直接Mock校验方法跳过异常即可:
@SpringBootTest public class Class1Test { @MockBean private Class2 class2; @Autowired private Class1 class1; @Test public void testTargetMethod() { // 模拟校验方法不抛出异常 doNothing().when(class2).validateCondition(); class1.targetMethod(); // 后续验证逻辑 } }
内容的提问来源于stack exchange,提问作者L.Th
相关产品推荐
相关产品推荐

