業務代碼中不常見場景的單元測試寫法

這是我參與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;
    
 }
複製代碼
相關文章
相關標籤/搜索