首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ApplicationContext.getBean(类)返回null的Junit测试用例

ApplicationContext.getBean(类)返回null的Junit测试用例
EN

Stack Overflow用户
提问于 2022-10-08 16:31:54
回答 2查看 198关注 0票数 0

当试图为applicationContext.getBean编写测试用例时(类名)。获取空指针异常。下面是Java类

代码语言:javascript
运行
复制
@Service
@Slf4j
public class MyClassName {

  @Autowired
  ServiceOne serviceOne;

  @Autowired
  ApplicationContext applicationContext;


  public getCitizenData(String mobileNumber) {

    CitizenDataService citizenDataService = applicationContext.getBean(CitizenDataService.class, mobileNumber);
    log.info("Getting Data");
    return citizenDataService.searchMethod(mobileNumber)
         // While debugging test file citizenDataService is coming as Null Hence getting Null Pointer exception
        .flatMap(.............
         )

测试文件

代码语言:javascript
运行
复制
class MyClassNameTest {

  private MyClassName mockMyClassName;

  @BeforeEach
  void setUp() {
    mockMyClassName = new MyClassName();
    mockMyClassName.serviceOne = mock(ServiceOne.class);
    mockMyClassName.applicationContext = mock(ApplicationContext.class);
    //mockMyClassName.applicationContext.getAutowireCapableBeanFactory();
  }

  @Test
  void testGetCitizenData() {
    // Setup
    // Configure ApplicationContext.getBean(...).
    final CitizenDataService citizenDataService = new CitizenDataService("mobileNumber");
    when(mockMyClassName.applicationContext.getBean(CitizenDataService.class, "args"))
        .thenReturn(citizenDataService);

    final result = mockMyClassName.getCitizenData("mobileNumber");
    // While debugging this citizenDataService is coming as Null Hence getting Null Pointer exception

如何编写测试用例?

EN

回答 2

Stack Overflow用户

发布于 2022-10-08 17:06:58

这是因为您在模拟的getBean()上对不正确的参数进行了存根。当调用模拟上的方法但没有匹配的存根参数时,默认情况下,它将返回null或空集合,或返回int/Integer的0,对于布尔/布尔值返回false。因此,在您的情况下,返回空CitizenDataService

更改以下内容可以解决您的问题:

代码语言:javascript
运行
复制
 when(mockMyClassName.applicationContext.getBean(CitizenDataService.class, "mobileNumber"))
    .thenReturn(citizenDataService);

另一种方法不是模拟ApplicationContext,而是使用spring测试来真正启动spring容器,其中包括测试用例所需的bean:

代码语言:javascript
运行
复制
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {MyClassName.class,ServiceOne.class,CitizenDataService.class})
public class MyClassNameTest {

     @Autowired
     private MyClassName myClassName
  

      @Test
      void testGetCitizenData() { 

     }

}

这将比普通的Mockito方法慢,因为它需要更多的时间来启动spring容器,还需要您管理上下文中包含的bean。

对我来说,我会重构您的类,这样它就不需要自动将ApplicationContext放入其中,然后编写一个普通的Mockito测试。手动从ApplicationContext获取bean并不是一个很好的实践,这将使类耦合到spring框架代码。

票数 0
EN

Stack Overflow用户

发布于 2022-10-11 11:44:48

我不建议模拟应用程序上下文。有太多的方法有相似的论点,很难嘲笑正确的方法。相反,可以使用专门为在测试中使用而编写的一个现成的实现,例如StaticApplicationContext

代码语言:javascript
运行
复制
class MyClassNameTest {
  private MyClassName mockMyClassName;
  private ApplicationContext appCtx;

  @BeforeEach
  void setUp() {
    mockMyClassName = new MyClassName();
    mockMyClassName.serviceOne = mock(ServiceOne.class);
    this.appCtx = new StaticApplicationContext();
  }

  @Test
  void testGetCitizenData() {
    appctx.registerBean(CitizenDataService.class, () -> new CitizenDataService("mobileNumber"));

    final result = mockMyClassName.getCitizenData("mobileNumber");
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73998715

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档