""" 凭证生成引擎单元测试 测试 VoucherGeneratorService 的核心逻辑 """ import pytest from unittest.mock import AsyncMock, MagicMock, patch from app.services.voucher.generator import VoucherGeneratorService, VoucherEntry @pytest.fixture def mock_db(): return AsyncMock() @pytest.fixture def generator(mock_db): return VoucherGeneratorService(mock_db) class TestVoucherEntry: """凭证分录测试""" def test_entry_creation(self): """测试创建借方分录""" entry = VoucherEntry( account_code="6601.01", account_name="管理费用-工资", debit_amount=10000, summary="基本工资", ) assert entry.account_code == "6601.01" assert entry.debit_amount == 10000 assert entry.credit_amount == 0 def test_entry_to_dict(self): """测试分录转字典""" entry = VoucherEntry( account_code="2211.01", account_name="应付职工薪酬", credit_amount=10000, summary="基本工资", department="技术部", ) d = entry.to_dict() assert d["account_code"] == "2211.01" assert d["credit_amount"] == 10000 assert d["department"] == "技术部" class TestVoucherGeneratorService: """凭证生成引擎测试""" def test_aggregate_by_field(self, generator): """测试按字段汇总""" records = [ {"基本工资": 10000, "奖金": 2000, "养老保险(公司)": 2000}, {"基本工资": 8000, "奖金": 1000, "养老保险(公司)": 1600}, ] totals = generator._aggregate_by_field(records) assert totals["基本工资"] == 18000 assert totals["奖金"] == 3000 assert totals["养老保险(公司)"] == 3600 def test_aggregate_empty(self, generator): """测试空数据汇总""" totals = generator._aggregate_by_field([]) assert totals == {} def test_generate_entries_basic(self, generator): """测试基本分录生成""" field_totals = {"基本工资": 18000} mappings = { "基本工资": { "debit_account": "6601.01", "debit_account_name": "管理费用-工资", "credit_account": "2211.01", "credit_account_name": "应付职工薪酬-工资", } } entries = generator._generate_entries(field_totals, mappings) assert len(entries) >= 2 total_debit = sum(e.debit_amount for e in entries) total_credit = sum(e.credit_amount for e in entries) assert total_debit == 18000 assert total_credit == 18000 def test_generate_entries_skip_missing_mapping(self, generator): """测试跳过无映射的字段""" field_totals = {"基本工资": 18000, "未知字段": 5000} mappings = { "基本工资": { "debit_account": "6601.01", "debit_account_name": "管理费用-工资", "credit_account": "2211.01", "credit_account_name": "应付职工薪酬-工资", } } entries = generator._generate_entries(field_totals, mappings) total_debit = sum(e.debit_amount for e in entries) assert total_debit == 18000 def test_merge_entries_same_account(self, generator): """测试合并相同科目""" entries = [ VoucherEntry("6601.01", "管理费用-工资", debit_amount=10000, summary="基本工资"), VoucherEntry("6601.01", "管理费用-工资", debit_amount=8000, summary="奖金"), ] merged = generator._merge_entries(entries) assert len(merged) == 1 assert merged[0].debit_amount == 18000