Short answer
你必须解开代理并在目标对象上设置字段:
ReflectionTestUtils.setField(unwrapFooService(), "fooDao", mockFooDao);
在unwrapFooService()可被定义为如下:
private FooServiceImpl unwrapFooService() {
if(AopUtils.isAopProxy(fooService) && fooService instanceof Advised) {
Object target = ((Advised) fooService).getTargetSource().getTarget();
return (FooServiceImpl)target;
}
return null;
}
…long one
这个问题很复杂,但是可以解决。你已经猜到这是使用cglib代理的副作用。原则上,Spring创建你的FooServiceImpl
名为的子类,类似于FooServiceImpl$EnhancerBycglib
。该子类包含对原始以及所有字段的引用(这是可以理解的-这是一个子类)。FooServiceImplFooServiceImpl
因此实际上有两个变量:FooServiceImpl$EnhancerBycglib.fooDao
和FooServiceImpl.fooDao
。你分配一个模拟前者,但你的服务使用后者。我写了前段时间关于这个陷阱。