""" 岗位服务单元测试(P4 服务层改造标杆) ============================================================= 验证 P4 改造后的服务层契约: - 服务函数「入参数据、出参数据」 - 业务失败通过 raise BizError 表达(不再 return R.failed) - 纯函数与可 mock 路径无需数据库即可测试 """ import pytest from src.core.exceptions import BizError from src.modules.system.position import service as position_service class TestBuildPageData: """分页数据构建(纯函数)""" def test_shape(self): data = position_service._build_page_data([], 0, 10, 1, 0) assert data == {'records': [], 'total': 0, 'size': 10, 'current': 1, 'pages': 0} class TestAddPosition: """添加岗位""" def test_empty_data_raises_bizerror(self, flask_app): """空数据触发表单验证失败 → BizError(FlaskForm 需应用上下文)""" with flask_app.app_context(): with pytest.raises(BizError): position_service.add_position({}) class TestUpdatePosition: """更新岗位""" def test_empty_data_raises_bizerror(self, flask_app): with flask_app.app_context(): with pytest.raises(BizError): position_service.update_position({}) class TestUpdateStatus: """状态设置""" def test_empty_data_raises_bizerror(self, flask_app): with flask_app.app_context(): with pytest.raises(BizError): position_service.update_position_status({}) class TestDeletePositions: """批量删除""" def test_empty_raises(self): """空 ID 触发 BizError""" with pytest.raises(BizError, match="记录ID不存在"): position_service.delete_positions('') def test_invalid_ids_raises(self): """非数字 ID 解析为空 → BizError""" with pytest.raises(BizError, match="无效的记录ID"): position_service.delete_positions('abc') def test_parse_and_delete(self, monkeypatch): """ID 解析后调用模型批量删除,返回删除计数""" from src.modules.system.position.models import Position captured = {} def fake_batch_delete(cls, ids): captured['ids'] = ids return len(ids) monkeypatch.setattr(Position, 'batch_delete', classmethod(fake_batch_delete)) count = position_service.delete_positions('1,2,3') assert count == 3 assert captured['ids'] == [1, 2, 3]