首页 > 解决方案 > 模拟自动装配的 bean 会引发 NullPointerException

问题描述

我在 Spring 中有以下类结构。

基类

public abstract class BaseClass {

    @Autowired
    protected ServiceA serviceA;

    public final void handleMessage() {
        String str = serviceA.getCurrentUser();
    }
}

我的控制器

@Component
public class MyController extends BaseClass {
    // Some implementation
    // Main thing is ServiceA is injected here
}

到目前为止,这工作正常,我可以看到ServiceA注入也正确。

问题是在ServiceA下面的测试中进行模拟时。

我的控制器测试

@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
@SpringBootTest
public class MyControllerTest {
    @MockBean
    private ServiceA serviceA;

    @MockBean
    private MyController myController;

    @Before
    public void init() {
        when(serviceA.getCurrentUser()).thenReturn(some object);
    }

    @Test
    public void firstTest() {
        myController.handleMessage(); // ---> Throws NPE stating that serviceA is null
    }
}

如前所述,它抛出一个NullPointerException. when.thenReturn尽管在嘲笑 bean 时没有任何影响,但我不太明白为什么。

标签: javaspringmockito

解决方案


因为您使用的是 Spring 控制器,所以您需要通过 @Autowired 注释从 SpringContext 导入您的控制器:

@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
@SpringBootTest
public class MyControllerTest {
    @MockBean
    private ServiceA serviceA;

    @Autowired // import through Spring
    private MyController myController;

    @Before
    public void init() {
        when(serviceA.getCurrentUser()).thenReturn(some object);
    }

    @Test
    public void firstTest() {
        myController.handleMessage(); // ---> Throws NPE stating that serviceA is null
    }
}

@MockBean被添加到 SpringContext 中,因此它们将作为依赖项注入到您的控制器中。


推荐阅读