dramaling-vocab-learning/backend/DramaLing.Api.Tests/Integration/Mocks/MockGeminiClient.cs

145 lines
4.5 KiB
C#

using DramaLing.Api.Services.AI.Gemini;
using System.Text.Json;
namespace DramaLing.Api.Tests.Integration.Mocks;
/// <summary>
/// 測試用的 Mock Gemini Client
/// 提供穩定可預測的 AI 服務回應,不依賴外部 API
/// </summary>
public class MockGeminiClient : IGeminiClient
{
/// <summary>
/// 模擬 Gemini API 調用
/// 根據 prompt 內容返回預定義的測試回應
/// </summary>
public async Task<string> CallGeminiAPIAsync(string prompt)
{
await Task.Delay(50); // 模擬 API 延遲
// 根據 prompt 類型返回不同的 mock 回應
if (prompt.Contains("generate distractors") || prompt.Contains("混淆選項"))
{
return GenerateDistractorsMockResponse(prompt);
}
if (prompt.Contains("analyze sentence") || prompt.Contains("句子分析"))
{
return GenerateSentenceAnalysisMockResponse(prompt);
}
if (prompt.Contains("synonyms") || prompt.Contains("同義詞"))
{
return GenerateSynonymsMockResponse(prompt);
}
// 預設回應
return JsonSerializer.Serialize(new
{
response = "Mock response from Gemini API",
timestamp = DateTime.UtcNow,
prompt_length = prompt.Length
});
}
/// <summary>
/// 測試連線 - 在測試環境中永遠回傳成功
/// </summary>
public async Task<bool> TestConnectionAsync()
{
await Task.Delay(10);
return true;
}
private string GenerateDistractorsMockResponse(string prompt)
{
// 從 prompt 中提取目標詞彙 (簡化邏輯)
var targetWord = ExtractTargetWord(prompt);
var distractors = targetWord.ToLower() switch
{
"hello" => new[] { "goodbye", "welcome", "thanks" },
"beautiful" => new[] { "ugly", "plain", "ordinary" },
"sophisticated" => new[] { "simple", "basic", "crude" },
_ => new[] { "option1", "option2", "option3" }
};
return JsonSerializer.Serialize(new
{
distractors = distractors,
target_word = targetWord,
generated_at = DateTime.UtcNow
});
}
private string GenerateSentenceAnalysisMockResponse(string prompt)
{
return JsonSerializer.Serialize(new
{
analysis = new
{
difficulty = "A2",
grammar_points = new[] { "present simple", "adjectives" },
vocabulary = new[] { "basic", "intermediate" },
suggestions = new[] { "Good sentence structure", "Clear meaning" }
},
words = new[]
{
new
{
word = "example",
translation = "範例",
part_of_speech = "noun",
difficulty = "A2",
synonyms = new[] { "sample", "instance" }
}
},
generated_at = DateTime.UtcNow
});
}
private string GenerateSynonymsMockResponse(string prompt)
{
var targetWord = ExtractTargetWord(prompt);
var synonyms = targetWord.ToLower() switch
{
"hello" => new[] { "hi", "greetings", "salutations" },
"beautiful" => new[] { "gorgeous", "stunning", "lovely" },
"sophisticated" => new[] { "refined", "elegant", "cultured" },
_ => new[] { "synonym1", "synonym2", "synonym3" }
};
return JsonSerializer.Serialize(synonyms);
}
private string ExtractTargetWord(string prompt)
{
// 簡化的詞彙提取邏輯
// 實際實作中可能會更複雜
var words = prompt.Split(' ');
// 尋找可能的目標詞彙
foreach (var word in words)
{
var cleanWord = word.Trim('"', '\'', ',', '.', '!', '?').ToLower();
if (cleanWord.Length > 2 && !IsCommonWord(cleanWord))
{
return cleanWord;
}
}
return "unknown";
}
private bool IsCommonWord(string word)
{
var commonWords = new HashSet<string>
{
"the", "and", "or", "but", "for", "with", "from", "to", "of", "in", "on", "at",
"generate", "create", "make", "find", "get", "give", "word", "words", "options"
};
return commonWords.Contains(word);
}
}