Skip to main content
Glama
gqy20

Europe PMC Literature Search MCP Server

test_openalex_service.py10.7 kB
""" OpenAlex 服务单元测试 """ from unittest.mock import Mock from unittest.mock import patch import pytest from src.openalex_service import OpenAlexService class TestOpenAlexService: """OpenAlex 服务测试类""" @pytest.fixture def service(self, logger): """创建 OpenAlex 服务实例""" return OpenAlexService(logger) def test_init(self, service): """测试服务初始化""" assert service.base_url == "https://api.openalex.org" assert service.api_client is not None assert hasattr(service, "search_works") assert hasattr(service, "get_work_by_doi") @patch("src.openalex_service.get_api_client") def test_search_works_success(self, mock_get_client, service): """测试成功搜索""" mock_client = Mock() mock_client.get.return_value = { "success": True, "data": { "results": [ { "id": "https://openalex.org/123456", "title": "Test Article", "authorships": [{"author": {"display_name": "Test Author"}}], "primary_location": { "source": {"display_name": "Test Journal"}, "doi": "10.1234/test", }, "publication_year": 2023, "open_access": { "is_oa": True, "oa_url": "https://example.com/fulltext.pdf", }, } ], "meta": {"count": 1}, }, } mock_get_client.return_value = mock_client service = OpenAlexService(None) result = service.search_works("test query", max_results=10) assert result["success"] is True assert len(result["articles"]) == 1 assert result["total_count"] == 1 assert result["source"] == "openalex" @patch("src.openalex_service.get_api_client") def test_search_works_api_failure(self, mock_get_client, service): """测试 API 调用失败""" mock_client = Mock() mock_client.get.return_value = {"success": False, "error": "API Error"} mock_get_client.return_value = mock_client service = OpenAlexService(None) result = service.search_works("test query", max_results=10) assert result["success"] is False assert result["error"] == "API调用失败" assert len(result["articles"]) == 0 @patch("src.openalex_service.get_api_client") def test_search_works_with_filters(self, mock_get_client, service): """测试带过滤器的搜索""" mock_client = Mock() mock_client.get.return_value = { "success": True, "data": {"results": [], "meta": {"count": 0}}, } mock_get_client.return_value = mock_client service = OpenAlexService(None) filters = {"publication_year": "2023"} result = service.search_works("test query", max_results=10, filters=filters) assert result["success"] is True assert len(result["articles"]) == 0 def test_format_single_article_complete(self, service): """测试格式化完整文章数据""" item = { "id": "https://openalex.org/123456", "title": "Test Article Title", "authorships": [ {"author": {"display_name": "Test Author"}, "author_position": "first"} ], "primary_location": { "source": {"display_name": "Test Journal"}, "doi": "10.1234/test.2023", }, "publication_year": 2023, "open_access": { "is_oa": True, "oa_url": "https://example.com/fulltext.pdf", "oa_status": "green", }, } result = service._format_single_article(item) assert result["title"] == "Test Article Title" assert result["authors"] == ["Test Author"] assert result["doi"] == "10.1234/test.2023" assert result["journal"] == "Test Journal" assert result["publication_date"] == "2023" assert result["open_access"]["is_oa"] is True assert result["open_access"]["oa_url"] == "https://example.com/fulltext.pdf" assert result["source"] == "openalex" def test_format_single_article_minimal(self, service): """测试格式化最少的文章数据""" item = {} result = service._format_single_article(item) assert result["title"] == "" assert result["authors"] == [] assert result["doi"] is None assert result["journal"] == "" assert result["publication_date"] == "" assert result["open_access"]["is_oa"] is False assert result["open_access"]["oa_url"] == "" assert result["open_access"]["oa_status"] == "" assert result["source"] == "openalex" def test_format_single_article_with_none_values(self, service): """测试格式化包含 None 值的文章数据""" item = { "title": None, "authorships": None, "primary_location": None, "publication_year": None, "open_access": None, } result = service._format_single_article(item) assert result["title"] == "" assert result["authors"] == [] assert result["doi"] is None assert result["journal"] == "" assert result["publication_date"] == "" assert result["open_access"]["is_oa"] is False assert result["source"] == "openalex" def test_format_single_article_with_none_primary_location(self, service): """测试 primary_location 为 None 的情况""" item = { "title": ["Test Article"], "authorships": [{"author": {"display_name": "Test Author"}}], "primary_location": None, "publication_year": 2023, } result = service._format_single_article(item) assert result["title"] == "Test Article" assert result["authors"] == ["Test Author"] assert result["doi"] is None assert result["journal"] == "" assert result["publication_date"] == "2023" def test_format_articles(self, service): """测试文章列表格式化""" items = [ { "title": "Article 1", "authorships": [{"author": {"display_name": "Author 1"}}], "primary_location": {"doi": "10.1234/1"}, "publication_year": 2023, }, { "title": "Article 2", "authorships": [{"author": {"display_name": "Author 2"}}], "primary_location": {"doi": "10.1234/2"}, "publication_year": 2023, }, ] result = service._format_articles(items) assert len(result) == 2 assert result[0]["title"] == "Article 1" assert result[1]["title"] == "Article 2" def test_format_articles_empty_list(self, service): """测试空文章列表格式化""" result = service._format_articles([]) assert result == [] @patch("src.openalex_service.get_api_client") def test_get_work_by_doi_success(self, mock_get_client): """测试通过 DOI 获取文章成功""" mock_client = Mock() mock_client.get.return_value = { "success": True, "data": { "results": [ { "id": "https://openalex.org/123456", "title": "Test Article", "doi": "10.1234/test", } ] }, } mock_get_client.return_value = mock_client service = OpenAlexService(None) result = service.get_work_by_doi("10.1234/test") assert result["success"] is True assert result["article"]["title"] == "Test Article" @patch("src.openalex_service.get_api_client") def test_get_work_by_doi_not_found(self, mock_get_client): """测试通过 DOI 获取文章未找到""" mock_client = Mock() mock_client.get.return_value = {"success": True, "data": {"results": []}} mock_get_client.return_value = mock_client service = OpenAlexService(None) result = service.get_work_by_doi("10.9999/nonexistent") assert result["success"] is False assert result["article"] is None def test_lru_cache_behavior(self, service): """测试 LRU 缓存行为""" with patch.object(service, "api_client") as mock_client: mock_client.get.return_value = { "success": True, "data": {"results": [], "meta": {"count": 0}}, } # 第一次调用 result1 = service.search_works("test", max_results=5) # 第二次调用应该使用缓存 result2 = service.search_works("test", max_results=5) # 验证只调用了一次 API assert mock_client.get.call_count == 1 assert result1 == result2 @patch("src.openalex_service.get_api_client") def test_get_citations(self, mock_get_client): """测试获取引用文献""" mock_client = Mock() mock_client.get.return_value = { "success": True, "data": { "results": [ { "id": "https://openalex.org/789012", "title": "Citing Article", "authorships": [{"author": {"display_name": "Citing Author"}}], "primary_location": { "source": {"display_name": "Citing Journal"}, "doi": "10.5678/citing", }, "publication_year": 2023, } ] }, } mock_get_client.return_value = mock_client service = OpenAlexService(None) # 由于 OpenAlex 服务没有 get_citations 方法,我们可以模拟添加一个 if not hasattr(service, "get_citations"): # 如果方法不存在,跳过这个测试 pytest.skip("OpenAlex service does not have get_citations method") result = service.get_citations("10.1234/cited", max_results=5) assert result["success"] is True assert len(result["citations"]) == 1

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/gqy20/article-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server