Spring ReflectionTestUtils 没有设置原始数据类型字段

Spring ReflectionTestUtils does not set primitive data type field

我使用 ReflectionTestUtils 在我的服务 class 中设置 int 字段来测试 class。 我的服务 class 喜欢:

@Service
public class SampleService {

    @Value("${app.count}")
    private int count;

    @Value("${app.countStr}")
    private String countStr;

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public String getCountStr() {
        return countStr;
    }

    public void setCountStr(String countStr) {
        this.countStr = countStr;
    }

    @PostConstruct
    public int demoMethod() {
        return count + Integer.parseInt(countStr);
    }
}

测试 class 就像:

@RunWith(SpringRunner.class)
public class SampleServiceTest {

    @Autowired
    private SampleService sampleService;

    @TestConfiguration
    static class SampleServiceTestConfig {

        @Bean
        public SampleService sampleService() {
            return new SampleService();
        }
    }

    @Before
    public void init() {
        ReflectionTestUtils.setField(sampleService, "count", new Integer(100));
        ReflectionTestUtils.setField(sampleService, "countStr", 100);
    }

    @Test
    public void testDemoMethod() {
        int a  = sampleService.demoMethod();
        Assert.assertTrue(a == 200);
    }
}

虽然我 运行 这个测试用例给出了以下错误:

Caused by: java.lang.NumberFormatException: For input string: "${app.count}"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:569)
    at java.lang.Integer.valueOf(Integer.java:766)
    at org.springframework.util.NumberUtils.parseNumber(NumberUtils.java:210)
    at org.springframework.beans.propertyeditors.CustomNumberEditor.setAsText(CustomNumberEditor.java:115)
    at org.springframework.beans.TypeConverterDelegate.doConvertTextValue(TypeConverterDelegate.java:466)
    at org.springframework.beans.TypeConverterDelegate.doConvertValue(TypeConverterDelegate.java:439)
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:192)
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:117)
    at org.springframework.beans.TypeConverterSupport.doConvert(TypeConverterSupport.java:70)
    ... 47 more

为什么 ReflectionTestUtils 尝试在字段中设置字符串值?

我放了2个字段,一个是整数,另一个是字符串,用于测试。

您可以找到源代码 here

请查看并提出解决方法。

测试时,您必须提供属性源。如果不添加属性,它会在变量中注入 @Value 内的值。在您的情况下,它会尝试将字符串添加到给出 NumberFormatException 的整数中。 尝试添加如下:

@RunWith(SpringRunner.class)
@TestPropertySource(properties = {"app.count=1", "app.countStr=sampleString"})
public class SampleServiceTest{...}

当您使用 @Autowired 时,它会在 ReflectionTestUtils 之前尝试在 @Value.

中添加值

您的问题是 初始化 spring 上下文并且服务由 Spring 在你的测试中 class.
这意味着这两个字段:

@Value("${app.count}")
private int count;

@Value("${app.countStr}")
private String countStr;

将具有在其 @Value 值中定义的值。
String countStr 可以用 "${app.countStr}" String 赋值(即使它没有意义)。
但是 int count 不能用 "${app.count}" String 赋值,因为 "${app.count}" 不能转换成 int 值 .
而作为 Integer.parseInt("${app.count}") 抛出的异常被调用:

Caused by: java.lang.NumberFormatException: For input string: "${app.count}"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:569)

要解决此问题,请按照 Nisheeth Shah 的建议使用 @TestPropertySource 在适当的时间提供属性值。

作为一般建议,限制反射的使用。它只在运行时检查,而且通常更不透明。