Bean only autowire仅在运行测试时失败

时间:2014-10-09 15:31:55

标签: java spring inheritance junit autowired

希望有人可能有这个问题的答案。 当我运行我的测试时,我遇到了一个autowire问题,而不是其他问题。 例外很清楚,因为它说“myField”缺失了。但是,该字段继承自基类。我无法在任何地方找到问题的答案,所以我会在这里试试运气。

例外

org.springframework.beans.factory.BeanCreationException: 
    Error creating bean with name 'myService': Injection of autowired dependencies failed; 
    nested exception is java.lang.NoSuchFieldError: myField

我的基类

public abstract class CommonStuff {
    protected String myField; // the one thats gone missing
    public abstract void setMyField(String myField);
}

我的服务

@Service("myService")
public class MyService extends CommonStuff {
    @Value("${myProperty.myField}")
    public void setMyField(String myField) {
        this.myField = myField;
    }
    ...
}

我的控制器

@Controller
public class MyController {
    @Autowired
    private MyService myService;        
    public void setMyService(MyService myService) {
        this.myService = myService;
    }
    ...
}

我的application-context.xml

似乎没有遗漏任何东西。

<context:component-scan base-package="com.myapp" />
<bean
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
    <property name="ignoreResourceNotFound" value="true" />
    <property name="locations">
        <list>
            <value>classpath:my.properties</value>              
            <value>classpath:myother.properties</value>
        </list>
    </property>
</bean>

my.properties

myProperty.myField=some value

我的测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:application-context.xml" })
public class MyControllerTest {
    @Autowired
    MyController myController;

    @Mock
    MyService myService;

    @Test
    public void myServiceTest() {
        // do stuff with myService
    }
    ...
}

问题

正如我所提到的,代码运行正常,但是每当我尝试运行测试时弹簧都无法自动装配。

问题不是测试,而是开始测试时的接线。以某种方式,spring无法从抽象的CommonStuff类中找到myField,因此它表示MyService没有该字段。

如果需要,我可以发布完整的堆栈跟踪,但我认为异常的本质已经存在。

1 个答案:

答案 0 :(得分:0)

我放弃并将myField移回服务并跳过setMyField。 现在就是这样。

基类

public abstract class CommonStuff {    
    public abstract String getMyField();
    public void doCommonStuff() {
        // use getMyField() 
    }
}

我的服务

@Service("myService")
public class MyService extends CommonStuff {
    @Value("${myProperty.myField}")
    private String myField;

    @Override
    public String getMyField() {
        return myField;
    }
    ...
}

这解决了我想要的问题,因为我现在可以从CommonStuff访问myField。