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

时间:2018-03-17 11:02:46

标签: java spring-boot junit spring-test

我使用ReflectionTestUtils在我的服务类中设置int字段来测试该类。 我的服务类如:

@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);
    }
}

和测试类就像:

@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尝试在字段中设置字符串值?

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

您可以找到源代码here

请查看并建议相同的解决方法。

2 个答案:

答案 0 :(得分:2)

您的问题是,使用@Before注释的方法在后调用初始化Spring上下文并且Spring在您的测试类中注入了该服务。
这意味着这两个领域:

@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,以便在适当的时间提供属性的值。

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

答案 1 :(得分:1)

在测试时,您必须提供属性源。如果您没有添加属性,它会在变量中注入Example: 1: ['YES', 'YES', 'NO', '123'] Example: 2: ['GONOW', 'MAKE'] Example: 3: ['YES'] 内的值。在您的情况下,它会尝试在提供@Value的整数中添加字符串。 尝试添加如下:

NumberFormatException

我希望它有所帮助。

当您使用@RunWith(SpringRunner.class) @TestPropertySource(properties = {"app.count=1", "app.countStr=sampleString"}) public class SampleServiceTest{...} 时,在@Autowired之前,它会尝试在ReflectionTestUtils内添加值。