test_biz_no_generator.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. """biz_no_generator 单元测试"""
  2. import unittest
  3. from unittest.mock import MagicMock, patch
  4. from sqlalchemy import create_engine
  5. from sqlalchemy.orm import sessionmaker
  6. from app.models.base import Base
  7. from app.models.models import BizBizNoSequence
  8. from app.crud.biz_no_generator import (
  9. MAX_SEQ,
  10. PREFIX_COLLECTION,
  11. PREFIX_DONATION,
  12. _format_biz_no,
  13. _prefix_for,
  14. )
  15. class TestBizNoGenerator(unittest.TestCase):
  16. def test_prefix_for(self):
  17. self.assertEqual(_prefix_for("collection"), PREFIX_COLLECTION)
  18. self.assertEqual(_prefix_for("donation"), PREFIX_DONATION)
  19. def test_format_biz_no(self):
  20. self.assertEqual(_format_biz_no("XBCC", "20260527", 1), "XBCC20260527000001")
  21. self.assertEqual(_format_biz_no("JZCC", "20260527", 42), "JZCC20260527000042")
  22. def test_max_seq(self):
  23. self.assertEqual(MAX_SEQ, 999999)
  24. class TestAllocateNextBizNo(unittest.TestCase):
  25. def test_sqlite_fallback_allocates_incrementing_numbers(self):
  26. from app.crud import biz_no_generator as gen
  27. engine = create_engine('sqlite:///:memory:')
  28. Base.metadata.create_all(engine, tables=[BizBizNoSequence.__table__])
  29. db = sessionmaker(bind=engine)()
  30. with patch.object(gen, 'assert_biz_no_available'):
  31. first = gen.allocate_next_biz_no(
  32. db,
  33. tenant_no='zkxw',
  34. kind='collection',
  35. biz_date=gen.datetime(2026, 10, 13),
  36. )
  37. second = gen.allocate_next_biz_no(
  38. db,
  39. tenant_no='zkxw',
  40. kind='collection',
  41. biz_date=gen.datetime(2026, 10, 13),
  42. )
  43. self.assertEqual(first, 'XBCC20261013000001')
  44. self.assertEqual(second, 'XBCC20261013000002')
  45. def test_allocate_raises_when_seq_exhausted(self):
  46. from app.crud import biz_no_generator as gen
  47. db = MagicMock()
  48. db.execute.side_effect = [
  49. None,
  50. MagicMock(scalar=lambda: MAX_SEQ + 1),
  51. ]
  52. with self.assertRaises(ValueError) as ctx:
  53. gen.allocate_next_biz_no(db, tenant_no="zkxw", kind="collection")
  54. self.assertIn("序号已用尽", str(ctx.exception))
  55. if __name__ == "__main__":
  56. unittest.main()