为什么在单元测试中使用@MockBean注解时bean没有被初始化

Why bean is not initialized when used @MockBean annotation in unit test

我的 bean 实现非常糟糕

@Component
public class Repository{
    public List<String> people= new ArrayList<>();

而且我还有一个测试,我用模拟替换存储库。 但是当我尝试通过存储库模拟访问测试中的“人”字段时,我得到 NullPointerException

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class MainControllerTest{

    @Autowired
    private MockMvc mockMvc;
        
    @MockBean
    private Repository repository;
           
    @Test
    public void someTest(){
        repository.people // null -> NullPointerException
    }
}

为什么会这样? bean 是否初始化过?实施如此糟糕的正确解决方案是什么?

Bean 已按预期使用 @MockBean 初始化。 它只为您生成一个存根。 Repository class 的所有嵌套内容都将被忽略。 在您的情况下,您有一个完全初始化的模拟。但当然它的嵌套字段是空的。因为它是模拟的,嵌套字段不会被初始化。 Mock 假定您只需要那种特定 class 的包装器来模拟其上的某些行为。

您需要做的是将@MockBean更改为@SpyBean。 在这种情况下,您的 class 字段将按照您的 Repository class 中的定义进行初始化。因此,您将拥有一个真正的 Repository 对象,但用 Mockito Spy 包裹。 它将允许您对该对象执行所有需要的测试操作。