test: add unit test framework and calculation service tests

This commit is contained in:
2026-06-21 05:31:03 +08:00
parent 83671834ca
commit 6212e0d92f
9 changed files with 271 additions and 7 deletions

View File

@@ -0,0 +1,14 @@
package com.healthlink.his;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
/**
* 单元测试基类 - 提供 Mockito 配置
*
* 子类只需继承此类即可获得 Mockito 注入支持。
* 所有 @InjectMocks 注入的依赖需在子类中用 @Mock 声明。
*/
@ExtendWith(MockitoExtension.class)
public abstract class BaseUnitTest {
}

View File

@@ -1,6 +1,6 @@
package com.healthlink.his.billing;
import com.core.common.utils.JsonNode;
import tools.jackson.databind.JsonNode;
import com.healthlink.his.web.BaseApiTest;
import org.junit.Test;
import org.junit.runner.RunWith;

View File

@@ -1,6 +1,6 @@
package com.healthlink.his.inpatient;
import com.core.common.utils.JsonNode;
import tools.jackson.databind.JsonNode;
import com.healthlink.his.web.BaseApiTest;
import org.junit.Test;
import org.junit.runner.RunWith;

View File

@@ -1,6 +1,6 @@
package com.healthlink.his.inspection;
import com.core.common.utils.JsonNode;
import tools.jackson.databind.JsonNode;
import com.healthlink.his.web.BaseApiTest;
import org.junit.Test;
import org.junit.runner.RunWith;

View File

@@ -0,0 +1,250 @@
package com.healthlink.his.payment;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.core.common.utils.SecurityUtils;
import com.healthlink.his.BaseUnitTest;
import com.healthlink.his.administration.domain.ChargeItem;
import com.healthlink.his.administration.domain.ChargeItemDefinition;
import com.healthlink.his.administration.service.IChargeItemDefinitionService;
import com.healthlink.his.administration.service.IChargeItemService;
import com.healthlink.his.common.enums.ChargeItemStatus;
import com.healthlink.his.financial.domain.PaymentRecDetail;
import com.healthlink.his.financial.domain.PaymentReconciliation;
import com.healthlink.his.financial.service.IPaymentRecDetailService;
import com.healthlink.his.financial.service.IPaymentReconciliationService;
import com.healthlink.his.web.paymentmanage.appservice.impl.ChargeBillCalculationService;
import com.healthlink.his.yb.enums.YbMedChrgItmType;
import com.healthlink.his.yb.enums.YbPayment;
import com.healthlink.his.yb.service.IClinicSettleService;
import com.healthlink.his.yb.service.IClinicUnSettleService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import java.math.BigDecimal;
import java.util.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
class ChargeBillCalculationServiceTest extends BaseUnitTest {
@InjectMocks
private ChargeBillCalculationService service;
@Mock
private IPaymentReconciliationService paymentReconciliationService;
@Mock
private IPaymentRecDetailService paymentRecDetailService;
@Mock
private IChargeItemService chargeItemService;
@Mock
private IChargeItemDefinitionService iChargeItemDefinitionService;
@Mock
private IClinicSettleService iClinicSettleService;
@Mock
private IClinicUnSettleService iClinicUnSettleService;
@Mock
private com.healthlink.his.administration.service.IAccountService iAccountService;
@Mock
private com.healthlink.his.administration.service.IEncounterService iEncounterService;
@Mock
private com.healthlink.his.financial.service.IContractService iContractService;
@Mock
private com.healthlink.his.administration.service.IInvoiceService iInvoiceService;
@Mock
private com.healthlink.his.administration.service.IPatientService iPatientService;
@Mock
private com.healthlink.his.administration.service.IOrganizationService iOrganizationService;
@Mock
private com.healthlink.his.administration.service.IPractitionerService iPractitionerService;
@Mock
private com.healthlink.his.web.paymentmanage.mapper.ChargeBillMapper chargeBillMapper;
private com.core.common.core.domain.model.LoginUser mockLoginUser;
@BeforeEach
void setUp() {
mockLoginUser = mock(com.core.common.core.domain.model.LoginUser.class);
doReturn("测试医院").when(mockLoginUser).getOptionJsonValue("fixmedinsName");
doReturn("TEST001").when(mockLoginUser).getOptionJsonValue("fixmedinsCode");
}
@SuppressWarnings("unchecked")
private <T> void mockList(com.baomidou.mybatisplus.extension.service.IService<T> svc, List<T> result) {
doReturn(result).when(svc).list(any(LambdaQueryWrapper.class));
}
@Test
void getTotal_emptyPaymentList_returnsZeroMap() {
mockList(paymentReconciliationService, Collections.emptyList());
try (MockedStatic<SecurityUtils> securityMock = mockStatic(SecurityUtils.class)) {
securityMock.when(SecurityUtils::getLoginUser).thenReturn(mockLoginUser);
Map<String, Object> result = service.getTotal("2026-01-01", "2026-01-31", null, null);
assertNotNull(result);
assertEquals(BigDecimal.ZERO, result.get("BED_FEE"));
assertEquals(BigDecimal.ZERO, result.get("DIAGNOSTIC_FEE"));
assertEquals(BigDecimal.ZERO, result.get("CHECK_FEE"));
assertEquals(BigDecimal.ZERO, result.get("SUM"));
assertEquals(BigDecimal.ZERO, result.get("cashSum"));
assertEquals("测试医院", result.get("fixmedinsName"));
assertEquals("TEST001", result.get("fixmedinsCode"));
}
}
@Test
void getTotal_withValidPayments_calculatesCorrectTotals() {
PaymentReconciliation pr = new PaymentReconciliation();
pr.setId(1L);
pr.setChargeItemIds("100,200");
pr.setPaymentEnum(1);
pr.setStatusEnum(1);
mockList(paymentReconciliationService, List.of(pr));
PaymentRecDetail detail1 = new PaymentRecDetail();
detail1.setReconciliationId(1L);
detail1.setPayEnum(YbPayment.SELF_CASH_PAY.getValue());
detail1.setAmount(new BigDecimal("100.00"));
PaymentRecDetail detail2 = new PaymentRecDetail();
detail2.setReconciliationId(1L);
detail2.setPayEnum(YbPayment.SELF_CASH_PAY.getValue());
detail2.setAmount(new BigDecimal("50.00"));
mockList(paymentRecDetailService, List.of(detail1, detail2));
ChargeItem ci1 = createChargeItem(100L, 100L, new BigDecimal("100.00"));
ChargeItem ci2 = createChargeItem(200L, 200L, new BigDecimal("200.00"));
mockList(chargeItemService, List.of(ci1, ci2));
ChargeItemDefinition def1 = createDefinition(100L, YbMedChrgItmType.BED_FEE);
ChargeItemDefinition def2 = createDefinition(200L, YbMedChrgItmType.WEST_MEDICINE);
doReturn(List.of(def1, def2)).when(iChargeItemDefinitionService).listByIds(anyCollection());
try (MockedStatic<SecurityUtils> securityMock = mockStatic(SecurityUtils.class)) {
securityMock.when(SecurityUtils::getLoginUser).thenReturn(mockLoginUser);
Map<String, Object> result = service.getTotal("2026-01-01", "2026-01-31", null, null);
assertEquals(new BigDecimal("100.00"), result.get("BED_FEE"));
assertEquals(new BigDecimal("200.00"), result.get("WEST_MEDICINE"));
assertEquals(new BigDecimal("300.00"), result.get("SUM"));
assertEquals(new BigDecimal("150.00"), result.get("cashSum"));
}
}
@Test
void getTotal_multiplePaymentTypes_aggregatesCorrectly() {
PaymentReconciliation pr = new PaymentReconciliation();
pr.setId(1L);
pr.setChargeItemIds("100");
pr.setPaymentEnum(1);
pr.setStatusEnum(1);
mockList(paymentReconciliationService, List.of(pr));
PaymentRecDetail cashDetail = new PaymentRecDetail();
cashDetail.setReconciliationId(1L);
cashDetail.setPayEnum(YbPayment.SELF_CASH_PAY.getValue());
cashDetail.setAmount(new BigDecimal("100.00"));
PaymentRecDetail wxDetail = new PaymentRecDetail();
wxDetail.setReconciliationId(1L);
wxDetail.setPayEnum(YbPayment.SELF_CASH_VX_VALUE.getValue());
wxDetail.setAmount(new BigDecimal("200.00"));
PaymentRecDetail aliDetail = new PaymentRecDetail();
aliDetail.setReconciliationId(1L);
aliDetail.setPayEnum(YbPayment.SELF_CASH_ALI_VALUE.getValue());
aliDetail.setAmount(new BigDecimal("300.00"));
mockList(paymentRecDetailService, List.of(cashDetail, wxDetail, aliDetail));
ChargeItem ci = createChargeItem(100L, 100L, new BigDecimal("600.00"));
mockList(chargeItemService, List.of(ci));
ChargeItemDefinition def = createDefinition(100L, YbMedChrgItmType.DIAGNOSTIC_FEE);
doReturn(List.of(def)).when(iChargeItemDefinitionService).listByIds(anyCollection());
try (MockedStatic<SecurityUtils> securityMock = mockStatic(SecurityUtils.class)) {
securityMock.when(SecurityUtils::getLoginUser).thenReturn(mockLoginUser);
Map<String, Object> result = service.getTotal("2026-01-01", "2026-01-31", null, null);
assertEquals(new BigDecimal("100.00"), result.get("cashSum"));
assertEquals(new BigDecimal("200.00"), result.get("vxCashSum"));
assertEquals(new BigDecimal("300.00"), result.get("aliCashSum"));
assertEquals(new BigDecimal("600.00"), result.get("DIAGNOSTIC_FEE"));
assertEquals(new BigDecimal("600.00"), result.get("SUM"));
}
}
@Test
void getTotal_singleChargeItem_returnsCorrectCategorySum() {
PaymentReconciliation pr = new PaymentReconciliation();
pr.setId(1L);
pr.setChargeItemIds("100");
pr.setPaymentEnum(1);
pr.setStatusEnum(1);
mockList(paymentReconciliationService, List.of(pr));
PaymentRecDetail detail = new PaymentRecDetail();
detail.setReconciliationId(1L);
detail.setPayEnum(YbPayment.SELF_CASH_PAY.getValue());
detail.setAmount(new BigDecimal("50.00"));
mockList(paymentRecDetailService, List.of(detail));
ChargeItem ci = createChargeItem(100L, 100L, new BigDecimal("50.00"));
mockList(chargeItemService, List.of(ci));
ChargeItemDefinition def = createDefinition(100L, YbMedChrgItmType.OPERATION_FEE);
doReturn(List.of(def)).when(iChargeItemDefinitionService).listByIds(anyCollection());
try (MockedStatic<SecurityUtils> securityMock = mockStatic(SecurityUtils.class)) {
securityMock.when(SecurityUtils::getLoginUser).thenReturn(mockLoginUser);
Map<String, Object> result = service.getTotal("2026-01-01", "2026-01-31", null, null);
assertEquals(new BigDecimal("50.00"), result.get("OPERATION_FEE"));
assertEquals(new BigDecimal("50.00"), result.get("SUM"));
assertEquals(BigDecimal.ZERO, result.get("BED_FEE"));
assertEquals(BigDecimal.ZERO, result.get("WEST_MEDICINE"));
}
}
@Test
void getTotal_allCategoriesHaveDefaultZero() {
mockList(paymentReconciliationService, Collections.emptyList());
try (MockedStatic<SecurityUtils> securityMock = mockStatic(SecurityUtils.class)) {
securityMock.when(SecurityUtils::getLoginUser).thenReturn(mockLoginUser);
Map<String, Object> result = service.getTotal("2026-01-01", "2026-01-31", null, null);
String[] categories = {"BED_FEE", "DIAGNOSTIC_FEE", "CHECK_FEE", "DIAGNOSTIC_TEST_FEE",
"MEDICAL_EXPENSE_FEE", "OPERATION_FEE", "NURSING_FEE", "SANITARY_MATERIALS_FEE",
"WEST_MEDICINE", "CHINESE_MEDICINE_SLICES_FEE", "CHINESE_MEDICINE_FEE",
"GENERAL_CONSULTATION_FEE", "REGISTRATION_FEE", "OTHER_FEE", "SUM"};
for (String cat : categories) {
assertEquals(BigDecimal.ZERO, result.get(cat), cat + " should default to ZERO");
}
}
}
private ChargeItem createChargeItem(Long id, Long definitionId, BigDecimal totalPrice) {
ChargeItem ci = new ChargeItem();
ci.setId(id);
ci.setDefinitionId(definitionId);
ci.setTotalPrice(totalPrice);
ci.setStatusEnum(ChargeItemStatus.BILLED.getValue());
return ci;
}
private ChargeItemDefinition createDefinition(Long id, YbMedChrgItmType type) {
ChargeItemDefinition def = new ChargeItemDefinition();
def.setId(id);
def.setYbType(String.valueOf(type.getValue()));
def.setTypeCode("TEST_TYPE");
return def;
}
}

View File

@@ -1,6 +1,6 @@
package com.healthlink.his.pharmacy;
import com.core.common.utils.JsonNode;
import tools.jackson.databind.JsonNode;
import com.healthlink.his.web.BaseApiTest;
import org.junit.Test;
import org.junit.runner.RunWith;

View File

@@ -1,6 +1,6 @@
package com.healthlink.his.registration;
import com.core.common.utils.JsonNode;
import tools.jackson.databind.JsonNode;
import com.healthlink.his.web.BaseApiTest;
import org.junit.Test;
import org.junit.runner.RunWith;

View File

@@ -1,6 +1,6 @@
package com.healthlink.his.report;
import com.core.common.utils.JsonNode;
import tools.jackson.databind.JsonNode;
import com.healthlink.his.web.BaseApiTest;
import org.junit.Test;
import org.junit.runner.RunWith;

View File

@@ -1,6 +1,6 @@
package com.healthlink.his.web;
import com.core.common.utils.JsonNode;
import tools.jackson.databind.JsonNode;
import com.core.common.utils.JsonUtils;
import org.junit.Before;