【问题标题】:Why @MockBean does not mock my target repository class (returns null)?为什么@MockBean 不模拟我的目标存储库类(返回 null)?
【发布时间】:2021-02-15 12:50:16
【问题描述】:

这是我要测试的课程

@Component
public class PermissionCheck {

    @Autowired
    private MyEntityRepository myEntityRepository;

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

这里是测试类

@RunWith(SpringRunner.class)
public class PermissionCheckTests {

    @MockBean
    private MyEntityRepository myEntityRepository;

    private PermissionCheck permissionCheck;

    @Before
    public void before() {
        this.permissionCheck = new PermissionCheck();
    }

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

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

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

java.lang.NullPointerException
    at PermissionCheck.hasPermission(PermissionCheck.java:line1)
    at PermissionCheckTests.shouldHasPermission(PermissionCheckTests.java:line2)

上面的line1和line2指的是这两行

        MyEntity myEntity = myEntityRepository.findById(myEntityId);
        assertTrue(this.permissionCheck.hasPermission(0));

使用调试器时,我看到从PermissionCheckTests.shouldHasPermission 输入PermissionCheck.hasPermission 时,存储库字段

    @Autowired
    private MyEntityRepository myEntityRepository;

为空。

我通过参考来自不同地方的其他现有代码来创建这些类,并且没有真正理解如何注释(部分原因是时间不多了),所以如果有人不仅可以告诉我如何修复,而且为什么我错了,我真的很感激!

编辑:

我做了@Nikolas Charalambidis 建议的更改(谢谢!),所以我的PermissionCheck 课程现在看起来完全一样

@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="")}

稍微搜索一下,从this SO answer,我觉得我不应该@Autowired PermissionCheck,因为它是一个类,而不是一个接口。

这是否意味着我必须创建一个接口,@Autowired 并让PermissionCheck 实现它?这对我来说似乎是多余的,因为我不明白为什么我需要这样的接口。有没有办法让它工作而无需创建我将仅用于此目的的新界面?

【问题讨论】:

    标签: java spring-boot testing mockito


    【解决方案1】:

    PermissionCheck 类的实例未正确注入。测试以与生产代码相同的方式使用 Spring 容器。以下行不会注入myEntityRepository

    this.permissionCheck = new PermissionCheck();
    

    Spring: NullPointerException occurs when including a bean 部分回答了您的问题。你需要@Autowire这个东西。

    Spring 测试上下文也不例外。只要 @MockBean MyEntityRepository 作为模拟 bean 存在,PermissionCheck 就会以标准方式自动装配,使用模拟类优先而不是测试范围内的现有 bean .

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

    【讨论】:

    • 感谢您的建议!但我仍然有错误......你能看看问题的更新部分吗?
    • 我也问a new question
    猜你喜欢
    • 2021-12-08
    • 1970-01-01
    • 2021-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多