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

这是我参与8月更文挑战的第2天,活动详情查看:8月更文挑战java

使用构造器方式初始化

项目中大量使用了构造器方式注入,这种注入方式的好处有下列几种。markdown

  • 使用final关键字,保证依赖不可变
  • 省去了咱们对其检查,保证依赖不为空
  • 保证返回客户端(调用)的代码的时候是彻底初始化的状态
  • 避免了循环依赖
  • 提高了代码的可复用性

特别是循环依赖检查这方面,随着业务的扩展,当初的代码结构设置的不够合理,对代码不够熟悉等因素可能形成循环依赖的状况。以前发生过项目上线后,点击了相关功能才爆出系统异常,缘由就是产生了循环依赖。使用了构造器注入方式后,在项目启动的时候,就会抛出BeanCurrentlyInCreationException:Requested bean is currently in creation: Is there an unresolvable circular reference从而提醒避免循环依赖。app

这种场景能够直接使用@Mock和@InjectMockside

业务代码示例

@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来达到快速得到接口、减小代码的目的。post

业务代码示例

@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;
    
 }
复制代码
相关文章
相关标签/搜索