""" 知识库 RAG 单元测试 """ from __future__ import annotations import pytest from unittest.mock import patch, AsyncMock, MagicMock class TestKnowledgeService: """知识库服务测试""" @pytest.mark.unit @pytest.mark.asyncio async def test_search_empty_kb(self): """空知识库搜索返回空列表""" from app.services.knowledge_service import search mock_db = MagicMock() mock_query = MagicMock() mock_db.query.return_value = mock_query mock_query.filter.return_value = mock_query mock_query.all.return_value = [] mock_query.first.return_value = None results = await search(mock_db, kb_id="nonexistent", query="test") assert results == [] @pytest.mark.unit @pytest.mark.asyncio async def test_rag_query_no_results(self): """无检索结果时返回空上下文""" from app.services.knowledge_service import rag_query mock_db = MagicMock() mock_query = MagicMock() mock_db.query.return_value = mock_query mock_query.filter.return_value = mock_query mock_query.all.return_value = [] mock_query.first.return_value = None result = await rag_query(mock_db, kb_id="test", query="no results") assert result["found"] is False assert result["context"] == "" @pytest.mark.unit @pytest.mark.asyncio async def test_search_with_content(self): """模拟有内容的搜索结果""" from app.services.knowledge_service import search from app.models.knowledge_base import DocumentChunk mock_chunk = MagicMock(spec=DocumentChunk) mock_chunk.id = "chunk-1" mock_chunk.content = "test content about Python programming" mock_chunk.chunk_index = 0 mock_chunk.document_id = "doc-1" mock_chunk.metadata = {"filename": "test.txt"} mock_db = MagicMock() mock_query = MagicMock() mock_db.query.return_value = mock_query mock_query.filter.return_value = mock_query mock_query.all.return_value = [] with patch("app.services.knowledge_service.embedding_service.generate_embedding", AsyncMock(return_value=[0.1, 0.2, 0.3])): with patch("app.services.knowledge_service.embedding_service.similarity_search", AsyncMock(return_value=[ {"content_text": "test content about Python", "score": 0.85, "metadata": {}} ])): results = await search(mock_db, kb_id="test", query="Python") # 可能返回空(chunks filter 不匹配)但不报错 assert isinstance(results, list) class TestKnowledgeModels: """知识库模型测试""" @pytest.mark.unit def test_knowledge_base_model(self): from app.models.knowledge_base import KnowledgeBase kb = KnowledgeBase( name="Test KB", description="Test", user_id="user-1", chunk_size=500, chunk_overlap=50, ) assert kb.name == "Test KB" assert kb.chunk_size == 500 assert kb.chunk_overlap == 50 @pytest.mark.unit def test_document_model(self): from app.models.knowledge_base import Document doc = Document( kb_id="kb-1", filename="test.txt", file_type="txt", file_size=1024, status="completed", chunk_count=5, ) assert doc.filename == "test.txt" assert doc.status == "completed" assert doc.chunk_count == 5 @pytest.mark.unit def test_document_chunk_model(self): from app.models.knowledge_base import DocumentChunk chunk = DocumentChunk( document_id="doc-1", kb_id="kb-1", chunk_index=0, content="test content", embedding="[0.1, 0.2, 0.3]", metadata={"source": "test"}, ) assert chunk.chunk_index == 0 assert chunk.content == "test content"