Skip to content

Commit 669f169

Browse files
committed
♻️ Unit test fix: refactor voice_app #1177
1 parent 8bb04f2 commit 669f169

File tree

2 files changed

+40
-6
lines changed

2 files changed

+40
-6
lines changed

.github/workflows/auto-unit-test.yml

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,26 @@ jobs:
6868
echo "✅ All tests passed successfully."
6969
fi
7070
71-
- name: Upload coverage to Codecov
71+
# Detect architecture
72+
- name: Detect architecture
73+
id: arch
74+
run: echo "arch=$(uname -m)" >> $GITHUB_OUTPUT
75+
76+
# Use Python uploader on ARM
77+
- name: Upload coverage to Codecov (Python uploader on ARM)
78+
if: startsWith(steps.arch.outputs.arch, 'arm') || startsWith(steps.arch.outputs.arch, 'aarch64')
79+
run: |
80+
pip install --upgrade codecov
81+
codecov \
82+
-t ${{ secrets.CODECOV_TOKEN }} \
83+
-f test/coverage.xml \
84+
-F unittests \
85+
-n codecov-umbrella \
86+
-v
87+
88+
# Use official action on x86
89+
- name: Upload coverage to Codecov (Official Action on x86)
90+
if: steps.arch.outputs.arch == 'x86_64'
7291
uses: codecov/codecov-action@v4
7392
with:
7493
files: test/coverage.xml
@@ -77,4 +96,4 @@ jobs:
7796
name: codecov-umbrella
7897
fail_ci_if_error: false
7998
verbose: true
80-
directory: .
99+
directory: .

test/backend/services/test_voice_service.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def __init__(self, config):
2828
self.config = config
2929
self.check_connectivity = AsyncMock(return_value=True)
3030

31-
def generate_speech(self, text: str, stream: bool = False):
31+
async def generate_speech(self, text: str, stream: bool = False):
3232
"""Mock implementation that returns appropriate data based on stream parameter"""
3333
if stream:
3434
# Return an async generator for streaming
@@ -49,15 +49,17 @@ async def mock_audio_generator():
4949

5050
def mock_voice_dependencies(func):
5151
"""Decorator to apply all necessary mocks for voice service tests"""
52-
@patch('nexent.core.models.tts_model.TTSModel', MockTTSModel)
53-
@patch('nexent.core.models.stt_model.STTModel', MockSTTModel)
52+
@patch('services.voice_service.TTSModel', MockTTSModel)
53+
@patch('services.voice_service.STTModel', MockSTTModel)
5454
@patch('consts.const.TEST_VOICE_PATH', '/test/path')
5555
@patch('consts.const.SPEED_RATIO', 1.0)
5656
@patch('consts.const.VOICE_TYPE', 'test_voice_type')
5757
@patch('consts.const.CLUSTER', 'test_cluster')
5858
@patch('consts.const.TOKEN', 'test_token')
5959
@patch('consts.const.APPID', 'test_appid')
6060
def wrapper(*args, **kwargs):
61+
# Reset the global voice service instance to ensure test isolation
62+
services.voice_service._voice_service_instance = None
6163
return func(*args, **kwargs)
6264
return wrapper
6365

@@ -177,6 +179,19 @@ def test_stream_tts_to_websocket_success(self):
177179
"""Test successful TTS streaming to WebSocket"""
178180
service = VoiceService()
179181

182+
# Mock the TTS model's generate_speech method directly to avoid real WebSocket connections
183+
async def mock_generate_speech(text: str, stream: bool = False):
184+
if stream:
185+
async def mock_audio_generator():
186+
yield b"mock_audio_chunk_1"
187+
yield b"mock_audio_chunk_2"
188+
yield b"mock_audio_chunk_3"
189+
return mock_audio_generator()
190+
else:
191+
return b"mock_complete_audio_data"
192+
193+
service.tts_model.generate_speech = mock_generate_speech
194+
180195
# Mock WebSocket with client_state
181196
mock_websocket = Mock()
182197
mock_websocket.send_bytes = AsyncMock()
@@ -191,7 +206,7 @@ def test_stream_tts_to_websocket_success(self):
191206
# Test the method
192207
asyncio.run(service.stream_tts_to_websocket(mock_websocket, "Hello, world!"))
193208

194-
assert mock_websocket.send_bytes.call_count == 6
209+
assert mock_websocket.send_bytes.call_count == 3
195210
mock_websocket.send_json.assert_called_once_with({"status": "completed"})
196211

197212
@mock_voice_dependencies

0 commit comments

Comments
 (0)