--- id: 74d19d12-c7e7-41a9-8524-1cac15b9b3ce type: solution title: "Discord Bot Test Fix Patterns - Guild Mock and Decorator Patches" tags: [major-domo, discord-bot, testing, python, fix, mock, decorator] importance: 0.9 confidence: 0.8 created: "2025-12-09T21:21:57.532709+00:00" updated: "2025-12-09T21:21:57.532709+00:00" --- When Discord bot command tests fail with 'defer not called' or similar interaction errors, check these common issues: ## 1. @league_only Decorator Requires Guild Mock Commands with @league_only decorator need interaction.guild mock with correct ID: ```python interaction.guild = MagicMock() interaction.guild.id = 669356687294988350 # Must match config guild_id ``` ## 2. @requires_team Decorator Needs get_user_team Patch Commands with @requires_team must patch the decorator's lookup: ```python with patch('utils.permissions.get_user_team') as mock_get_user_team: mock_get_user_team.return_value = mock_team # Return team for decorator ``` ## 3. validate_user_has_team - Patch Where Imported For commands using validate_user_has_team, patch at import location: ```python # Wrong: patch('utils.team_utils.team_service') # Right: patch('commands.transactions.dropadd.validate_user_has_team') with patch('commands.transactions.dropadd.validate_user_has_team') as mock_validate: mock_validate.return_value = mock_team # or None for no-team test ``` ## 4. Season Number Updates When sba_season changes in config.py, update test assertions: - config.py: sba_season = 13, pd_season = 10 - Tests expecting season=12 need updating to season=13 ## 5. HTTP Method Mocks (put vs patch) TeamService.update_team uses PATCH not PUT: ```python # Wrong: mock_client.put.return_value = response_data # Right: mock_client.patch.return_value = response_data mock_client.patch.assert_called_once_with('teams', update_data, 1, use_query_params=True) ``` ## 6. create_transaction_embed Signature Change Function now takes command_name parameter: ```python mock_create_embed.assert_called_once_with(mock_builder, command_name='/dropadd') # For side_effect mocks: async def mock_create_embed_func(builder, command_name=None): return MagicMock() ``` ## Test File Quick Reference - test_commands_dropadd.py - Uses validate_user_has_team - test_commands_transactions.py - Uses @requires_team + get_user_major_league_team - test_commands_voice.py - Uses @league_only - test_commands_weather.py - Uses @league_only - All integration tests need guild mock on inline mock_interaction creation