Skip to main content
Glama
by kentaro
aivis-speech-service.test.ts4.54 kB
import axios from 'axios'; import fs from 'fs'; import path from 'path'; import wavPlayer from 'node-wav-player'; import { AivisSpeechService } from '../../services/aivis-speech-service'; import { Speaker, SynthesisRequest } from '../../types/aivis-speech'; // モジュールのモック jest.mock('axios'); jest.mock('fs'); jest.mock('path'); jest.mock('node-wav-player'); jest.mock('dotenv', () => ({ config: jest.fn() })); const mockedAxios = axios as jest.Mocked<typeof axios>; const mockedFs = fs as jest.Mocked<typeof fs>; const mockedPath = path as jest.Mocked<typeof path>; const mockedWavPlayer = wavPlayer as jest.Mocked<typeof wavPlayer>; describe('AivisSpeechService', () => { let service: AivisSpeechService; // テスト用のモックデータ const mockSpeakers: Speaker[] = [ { name: 'テストスピーカー1', speaker_id: 1, styles: [ { name: 'スタイル1', id: 1 }, { name: 'スタイル2', id: 2 }, ], version: '1.0.0', }, { name: 'テストスピーカー2', speaker_id: 2, styles: [ { name: 'スタイル3', id: 3 }, ], version: '1.0.0', }, ]; const mockAudioQuery = { text: 'こんにちは', style_id: 1, speed_scale: 1.0, pitch_scale: 1.0, intonation_scale: 1.0, volume_scale: 1.0, pre_phoneme_length: 0.1, post_phoneme_length: 0.1, output_sampling_rate: 24000 }; const mockAudioBuffer = Buffer.from('dummy audio data'); beforeEach(() => { // テスト前にモックをリセット jest.clearAllMocks(); // モックの設定 mockedPath.join.mockImplementation((...args) => args.join('/')); mockedFs.existsSync.mockReturnValue(true); mockedWavPlayer.play.mockResolvedValue(undefined); // サービスのインスタンスを作成 service = new AivisSpeechService(); }); describe('getSpeakers', () => { it('スピーカー一覧を取得できること', async () => { // モックの設定 mockedAxios.get.mockResolvedValueOnce({ data: mockSpeakers }); // テスト対象の関数を実行 const result = await service.getSpeakers(); // 結果の検証 expect(result).toEqual(mockSpeakers); expect(mockedAxios.get).toHaveBeenCalledTimes(1); expect(mockedAxios.get).toHaveBeenCalledWith(expect.stringContaining('/speakers')); }); it('APIエラー時に例外をスローすること', async () => { // モックの設定 mockedAxios.get.mockRejectedValueOnce(new Error('API error')); // テスト対象の関数を実行して例外をキャッチ await expect(service.getSpeakers()).rejects.toThrow('スピーカー一覧の取得に失敗しました'); // 呼び出しの検証 expect(mockedAxios.get).toHaveBeenCalledTimes(1); }); }); describe('synthesize', () => { it('音声合成を実行できること', async () => { // モックの設定 mockedAxios.post.mockResolvedValueOnce({ data: mockAudioQuery }); // audio_queryのレスポンス mockedAxios.post.mockResolvedValueOnce({ data: mockAudioBuffer }); // synthesisのレスポンス // テスト用のリクエスト const request: SynthesisRequest = { text: 'こんにちは', speaker: 1, style_id: 1, }; // テスト対象の関数を実行 const result = await service.synthesize(request); // 結果の検証 expect(result).toHaveProperty('audioData'); expect(mockedAxios.post).toHaveBeenCalledTimes(2); // audio_queryの呼び出しを検証 expect(mockedAxios.post.mock.calls[0][0]).toContain('/audio_query'); // synthesisの呼び出しを検証 expect(mockedAxios.post.mock.calls[1][0]).toContain('/synthesis'); // 一時ファイルの作成と再生を検証 expect(mockedFs.writeFileSync).toHaveBeenCalledTimes(1); expect(mockedWavPlayer.play).toHaveBeenCalledTimes(1); }); it('APIエラー時に例外をスローすること', async () => { // モックの設定 mockedAxios.post.mockRejectedValueOnce(new Error('API error')); // テスト用のリクエスト const request: SynthesisRequest = { text: 'こんにちは', speaker: 1, }; // テスト対象の関数を実行して例外をキャッチ await expect(service.synthesize(request)).rejects.toThrow('音声合成に失敗しました'); }); }); });

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/kentaro/aivis-speech-mcp'

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