为什么@Autowired 引发 UnsatisfiedDependencyException,即使 class 没有实现任何接口?

Why @Autowired raises UnsatisfiedDependencyException, even the class does not implement any interface?

这是我要测试的class

@Component
public class PermissionCheck {

    @Autowired
    private MyEntityRepository myEntityRepository;

    public boolean hasPermission(int myEntityID) {
        MyEntity myEntity = myEntityRepository.findById(myEntityId);
        return myEntity != null;
    }
}

这里是测试class

@RunWith(SpringRunner.class)
public class PermissionCheckTests {

    @Autowired                                     // you need to autowire
    private PermissionCheck permissionCheck;       // and it uses @MockBean dependency

    @MockBean                                      // if no such @MockBean exists
    private MyEntityRepository myEntityRepository; // the real implementation is used

    @Test
    public void shouldHasPermission() {
        MyEntity myEntity = new MyEntity();

        when(this.myEntityRepository.findById(any())).thenReturn(myEntity);
        assertTrue(this.permissionCheck.hasPermission(0));
    }
}

当我运行这个测试时我得到了

org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'PermissionCheckTests': 
Unsatisfied dependency expressed through field 'permissionCheck'; 
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type 'PermissionCheck' available: 
expected at least 1 bean which qualifies as autowire candidate. 
Dependency annotations: 
{@org.springframework.beans.factory.annotation.Autowired(required=true), 
@org.springframework.beans.factory.annotation.Qualifier(value="")}

从其他 SO 问题,例如 this one,我看到当目标 class 实现接口时会发生这种情况。但是从代码可以看出,PermissionCheck并没有实现任何接口,为什么还是会抛出异常呢?

这是否意味着我必须创建一个接口,@Autowired 它并让 PermissionCheck 实现它?这对我来说似乎是多余的,因为我不明白为什么我需要这样一个界面。有没有一种方法可以在不创建我将专门用于此目的的新界面的情况下使其工作?

@RunWith(SpringRunner.class) 不会自动加载您的 configurations/beans/properties 除非附有专门这样做的注释,例如 @ContextConfiguration@TestPropertySource.

如果您的是 Spring 引导应用程序并且您想要加载整个上下文以及所有属性,您只需将 @SpringBootTest 注释添加到您的测试 class。

参考文献: