浅谈业务代码中不常见场景的单元测试写法

发表于:2021-11-23 09:40

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:ShowMaker    来源:稀土掘金

分享:
  使用构造器方式初始化
  项目中大量使用了构造器方式注入,这种注入方式的好处有下列几种。
  · 使用final关键字,保证依赖不可变
  · 省去了我们对其检查,保证依赖不为空
  · 保证返回客户端(调用)的代码的时候是完全初始化的状态
  · 避免了循环依赖
  · 提升了代码的可复用性
  特别是循环依赖检查这方面,随着业务的扩展,当初的代码结构设置的不够合理,对代码不够熟悉等因素可能造成循环依赖的情况。之前发生过项目上线后,点击了相关功能才爆出系统异常,原因就是产生了循环依赖。使用了构造器注入方式后,在项目启动的时候,就会抛出BeanCurrentlyInCreationException:Requested bean is currently in creation: Is there an unresolvable circular reference从而提醒避免循环依赖。
  这种场景可以直接使用@Mock和@InjectMocks
  业务代码示例
  @Service
  public class EventService implements ModuleDtoQuery<EventDetailDTO> {
      private final AppService appService;
      private final EventRepo repo;
      @Autowired
      public EventService(AppService appService,
                          EventRepo repo) {
          this.appService = appService;
          this.repo = repo;
      }
   }

  单元测试代码示例
  @RunWith(PowerMockRunner.class)
  public class EventServiceTest {
      @Mock
      AppService appService;
      @Mock
      EventRepo repo;
      @InjectMocks
      EventService eventService;
      @Test
      public void queryList() {
      ...
      }   
  }

  构造器注入中加入了List -> Map
  通过接口注入了多个实现,再通过List转Map来达到快速获得接口、减少代码的目的。
  业务代码示例
  @Service
  public class CatalogService {
      private final CatalogRepo catalogRepo;
      private final CatalogAssembler catalogAssembler;
      private final Map<Integer, CountByCatalog> countByCatalogMap;
      @Autowired
      public CatalogService(CatalogRepo catalogRepo,
                            CatalogAssembler catalogAssembler,
                            List<CountByCatalog> countByCatalogList) {
          this.catalogRepo = catalogRepo;
          this.catalogAssembler = catalogAssembler;
          this.countByCatalogMap = countByCatalogList.stream()
                  .collect(Collectors.toMap(CountByCatalog::getCatalogType, v -> v));
      }
      
  }

  单元测试代码示例
  首先使用@Mock来模拟这个接口的集合,再手动写一些实现类,这样就可以达到我们模拟的要求了。
  @RunWith(PowerMockRunner.class)
  @PrepareForTest({SpringContextUtils.class})
  public class CatalogServiceTest {
      @Mock
      CatalogRepo catalogRepo;
      @Mock
      CatalogAssembler catalogAssembler;
      @Mock
      List<CountByCatalog> countByCatalog = Arrays.asList(new CountByCatalog() {
          @Override
          public int getCatalogType() {
              return 0;
          }
      });
      @InjectMocks
      CatalogService catalogService;
      
   }

  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
价值398元的测试课程免费赠送,填问卷领取吧!

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计

法律顾问:上海漕溪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2022
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号