Spaces:
Running
Running
| """Unit tests: Faithfulness checker — hallucination detection.""" | |
| import pytest | |
| from unittest.mock import AsyncMock, patch, MagicMock | |
| async def test_faithful_response_passes(): | |
| """A response directly supported by context should pass faithfulness check.""" | |
| try: | |
| from app.core.rag.faithfulness import FaithfulnessChecker | |
| checker = FaithfulnessChecker() | |
| context = "The book costs $19.99 and is available on Amazon." | |
| response = "You can get the book on Amazon for $19.99." | |
| with patch.object(checker, "_score", new_callable=AsyncMock, return_value=0.92): | |
| result = await checker.check(response=response, context=context) | |
| assert result.passed is True | |
| assert result.score >= 0.55 | |
| except (ImportError, AttributeError): | |
| pytest.skip("FaithfulnessChecker not importable with this interface") | |
| async def test_hallucinated_response_fails(): | |
| """A response containing unsupported claims should fail faithfulness.""" | |
| try: | |
| from app.core.rag.faithfulness import FaithfulnessChecker | |
| checker = FaithfulnessChecker() | |
| context = "The book is about a detective in London." | |
| response = "The book is a romance novel set in Paris and won the Nobel Prize." | |
| with patch.object(checker, "_score", new_callable=AsyncMock, return_value=0.12): | |
| result = await checker.check(response=response, context=context) | |
| assert result.passed is False | |
| except (ImportError, AttributeError): | |
| pytest.skip("FaithfulnessChecker not importable with this interface") | |
| def test_faithfulness_threshold_from_config(): | |
| """Threshold must match the config value — prevents silent config drift.""" | |
| from app.config import get_settings | |
| cfg = get_settings() | |
| assert 0.0 < cfg.RAG_FAITHFULNESS_THRESHOLD < 1.0 | |
| assert cfg.RAG_FAITHFULNESS_THRESHOLD == 0.55 | |