diff --git a/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/BaseUnitTest.java b/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/BaseUnitTest.java new file mode 100644 index 000000000..51c296420 --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/BaseUnitTest.java @@ -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 { +} diff --git a/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/billing/BillingApiTest.java b/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/billing/BillingApiTest.java index af2279cc9..e09cfc865 100644 --- a/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/billing/BillingApiTest.java +++ b/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/billing/BillingApiTest.java @@ -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; diff --git a/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/inpatient/InpatientApiTest.java b/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/inpatient/InpatientApiTest.java index b21094998..e063452fd 100644 --- a/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/inpatient/InpatientApiTest.java +++ b/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/inpatient/InpatientApiTest.java @@ -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; diff --git a/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/inspection/InspectionApiTest.java b/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/inspection/InspectionApiTest.java index bf972acff..7f34c2b84 100644 --- a/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/inspection/InspectionApiTest.java +++ b/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/inspection/InspectionApiTest.java @@ -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; diff --git a/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/payment/ChargeBillCalculationServiceTest.java b/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/payment/ChargeBillCalculationServiceTest.java new file mode 100644 index 000000000..47f338f48 --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/payment/ChargeBillCalculationServiceTest.java @@ -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 void mockList(com.baomidou.mybatisplus.extension.service.IService svc, List result) { + doReturn(result).when(svc).list(any(LambdaQueryWrapper.class)); + } + + @Test + void getTotal_emptyPaymentList_returnsZeroMap() { + mockList(paymentReconciliationService, Collections.emptyList()); + + try (MockedStatic securityMock = mockStatic(SecurityUtils.class)) { + securityMock.when(SecurityUtils::getLoginUser).thenReturn(mockLoginUser); + + Map 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 securityMock = mockStatic(SecurityUtils.class)) { + securityMock.when(SecurityUtils::getLoginUser).thenReturn(mockLoginUser); + + Map 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 securityMock = mockStatic(SecurityUtils.class)) { + securityMock.when(SecurityUtils::getLoginUser).thenReturn(mockLoginUser); + + Map 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 securityMock = mockStatic(SecurityUtils.class)) { + securityMock.when(SecurityUtils::getLoginUser).thenReturn(mockLoginUser); + + Map 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 securityMock = mockStatic(SecurityUtils.class)) { + securityMock.when(SecurityUtils::getLoginUser).thenReturn(mockLoginUser); + + Map 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; + } +} diff --git a/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/pharmacy/PharmacyApiTest.java b/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/pharmacy/PharmacyApiTest.java index 1bf08a40a..48d1f7a30 100644 --- a/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/pharmacy/PharmacyApiTest.java +++ b/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/pharmacy/PharmacyApiTest.java @@ -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; diff --git a/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/registration/RegistrationApiTest.java b/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/registration/RegistrationApiTest.java index 24f253614..bb3ddb8a8 100644 --- a/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/registration/RegistrationApiTest.java +++ b/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/registration/RegistrationApiTest.java @@ -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; diff --git a/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/report/ReportApiTest.java b/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/report/ReportApiTest.java index 0987cdea7..a04d9dcf0 100644 --- a/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/report/ReportApiTest.java +++ b/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/report/ReportApiTest.java @@ -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; diff --git a/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/web/BaseApiTest.java b/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/web/BaseApiTest.java index 98fd34c4e..80e3e695b 100644 --- a/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/web/BaseApiTest.java +++ b/healthlink-his-server/healthlink-his-application/src/test/java/com/healthlink/his/web/BaseApiTest.java @@ -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;