Skip to content

Commit e76bf0a

Browse files
Seaualclaude
andcommitted
test: add Neo4jStore unit tests with mocked driver
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent fa3854f commit e76bf0a

1 file changed

Lines changed: 170 additions & 0 deletions

File tree

tests/test_neo4j_store.py

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
"""
2+
Neo4jStore 单元测试(mock driver)
3+
"""
4+
import sys
5+
from pathlib import Path
6+
from unittest.mock import MagicMock
7+
8+
import pytest
9+
10+
sys.path.insert(0, str(Path(__file__).parent.parent))
11+
12+
from mkg.neo4j_store import Neo4jStore
13+
14+
15+
@pytest.fixture
16+
def mock_neo4j():
17+
"""创建 mock 的 Neo4jStore"""
18+
store = Neo4jStore.__new__(Neo4jStore)
19+
store.driver = MagicMock()
20+
store.connected = True
21+
yield store
22+
23+
24+
def test_sync_concept_when_connected(mock_neo4j):
25+
"""已连接时 sync_concept 应成功"""
26+
mock_neo4j.sync_concept({
27+
"id": "test-concept",
28+
"text": "Test Concept",
29+
"text_en": "Test",
30+
"text_zh": "测试",
31+
"category": "field",
32+
"paper_count": 5,
33+
})
34+
# 验证 driver.session 被调用
35+
mock_neo4j.driver.session.assert_called()
36+
37+
38+
def test_sync_concept_when_not_connected():
39+
"""未连接时 sync_concept 应返回 False"""
40+
store = Neo4jStore.__new__(Neo4jStore)
41+
store.connected = False
42+
store.driver = None
43+
44+
result = store.sync_concept({"id": "test", "text": "Test"})
45+
assert result is False
46+
47+
48+
def test_sync_relation_when_connected(mock_neo4j):
49+
"""已连接时 sync_relation 应成功"""
50+
mock_neo4j.sync_relation("parent", "child")
51+
mock_neo4j.driver.session.assert_called()
52+
53+
54+
def test_sync_relation_when_not_connected():
55+
"""未连接时 sync_relation 应返回 False"""
56+
store = Neo4jStore.__new__(Neo4jStore)
57+
store.connected = False
58+
store.driver = None
59+
60+
result = store.sync_relation("parent", "child")
61+
assert result is False
62+
63+
64+
def test_get_tree_returns_empty_when_not_connected():
65+
"""未连接时 get_tree 应返回空"""
66+
store = Neo4jStore.__new__(Neo4jStore)
67+
store.connected = False
68+
store.driver = None
69+
70+
result = store.get_tree()
71+
assert result == {}
72+
73+
74+
def test_get_children_returns_empty_when_not_connected():
75+
"""未连接时 get_children 应返回空列表"""
76+
store = Neo4jStore.__new__(Neo4jStore)
77+
store.connected = False
78+
store.driver = None
79+
80+
result = store.get_children("some-id")
81+
assert result == []
82+
83+
84+
def test_get_parents_returns_empty_when_not_connected():
85+
"""未连接时 get_parents 应返回空列表"""
86+
store = Neo4jStore.__new__(Neo4jStore)
87+
store.connected = False
88+
store.driver = None
89+
90+
result = store.get_parents("some-id")
91+
assert result == []
92+
93+
94+
def test_get_root_concepts_returns_empty_when_not_connected():
95+
"""未连接时 get_root_concepts 应返回空列表"""
96+
store = Neo4jStore.__new__(Neo4jStore)
97+
store.connected = False
98+
store.driver = None
99+
100+
result = store.get_root_concepts()
101+
assert result == []
102+
103+
104+
def test_get_all_concepts_returns_empty_when_not_connected():
105+
"""未连接时 get_all_concepts 应返回空列表"""
106+
store = Neo4jStore.__new__(Neo4jStore)
107+
store.connected = False
108+
store.driver = None
109+
110+
result = store.get_all_concepts()
111+
assert result == []
112+
113+
114+
def test_get_graph_data_returns_empty_when_not_connected():
115+
"""未连接时 get_graph_data 应返回空 nodes/edges"""
116+
store = Neo4jStore.__new__(Neo4jStore)
117+
store.connected = False
118+
store.driver = None
119+
120+
result = store.get_graph_data()
121+
assert result == {"nodes": [], "edges": []}
122+
123+
124+
def test_get_stats_returns_empty_when_not_connected():
125+
"""未连接时 get_stats 应返回空 dict"""
126+
store = Neo4jStore.__new__(Neo4jStore)
127+
store.connected = False
128+
store.driver = None
129+
130+
result = store.get_stats()
131+
assert result == {}
132+
133+
134+
def test_update_paper_count_when_not_connected():
135+
"""未连接时 update_paper_count 应返回 False"""
136+
store = Neo4jStore.__new__(Neo4jStore)
137+
store.connected = False
138+
store.driver = None
139+
140+
result = store.update_paper_count("test-id", 10)
141+
assert result is False
142+
143+
144+
def test_search_concepts_when_not_connected():
145+
"""未连接时 search_concepts 应返回空列表"""
146+
store = Neo4jStore.__new__(Neo4jStore)
147+
store.connected = False
148+
store.driver = None
149+
150+
result = store.search_concepts("test")
151+
assert result == []
152+
153+
154+
def test_close_sets_connected_false(mock_neo4j):
155+
"""close 应设置 connected 为 False"""
156+
assert mock_neo4j.connected is True
157+
mock_neo4j.close()
158+
assert mock_neo4j.connected is False
159+
160+
161+
def test_sync_all_from_sqlite_returns_error_when_not_connected():
162+
"""未连接时 sync_all_from_sqlite 应返回错误"""
163+
store = Neo4jStore.__new__(Neo4jStore)
164+
store.connected = False
165+
store.driver = None
166+
167+
result = store.sync_all_from_sqlite(MagicMock())
168+
assert result["concepts_synced"] == 0
169+
assert result["relations_synced"] == 0
170+
assert "error" in result

0 commit comments

Comments
 (0)