You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mock spotipy artist_albums未替换返回值却追加,测试调用实际API失败

问题修复方案

核心问题分析

你遇到的三个问题根源分别是:

  • Mock路径错误,导致实际Spotify API被调用
  • 断言逻辑错误,混淆了API调用记录与print输出的断言对象
  • 脚本未做防护,测试时自动执行了实际函数调用

分步修复

1. 修复Mock路径,避免实际API调用

在测试代码中,@patch的目标应该是被测试模块中导入的spotipy.Spotify,而非库本身的类。假设你的脚本文件名为spotify_playlist.py,需把@patch('spotipy.Spotify')改为@patch('spotify_playlist.spotipy.Spotify')。

原因:Python的Mock基于模块导入引用工作,必须替换被测试代码实际使用的类实例,才能拦截API调用。

2. 修复断言逻辑,正确验证print输出

原测试错误地将artist_albums的调用记录与print调用做对比,需改为Mockprint函数,再断言它的调用参数。

3. 脚本添加执行防护,避免测试时自动运行

把原脚本中直接调用see_album的代码放到if __name__ == '__main__':块中,这样测试导入模块时不会执行实际调用。


修改后的完整代码

原脚本(spotify_playlist.py)

import spotipy
from spotipy.oauth2 import SpotifyClientCredentials

def see_album(birdy_uri):
    spotify = spotipy.Spotify(client_credentials_manager=SpotifyClientCredentials())

    results = spotify.artist_albums(birdy_uri, album_type='album')
    
    albums = results['items']

    while results['next']:
        results = spotify.next(results)
        albums.extend(results['items'])

    for album in albums:
        print(album['name'])

# 添加执行防护,仅直接运行脚本时执行
if __name__ == '__main__':
    see_album('spotify:artist:2WX2uTcsvV5OnS0inACecP')

测试代码(test_spotify.py)

import unittest
from unittest.mock import Mock, patch, call
from spotify_playlist import see_album

class TestSeeAlbum(unittest.TestCase):
    # 修正patch路径为被测试模块中的spotipy.Spotify
    @patch('spotify_playlist.spotipy.Spotify')
    # 同时Mock内置print函数,用于断言输出
    @patch('builtins.print')
    def test_see_album(self, mock_print, mock_spotify):
        # 创建mock的Spotify实例
        mock_spotify_instance = Mock()
        mock_spotify.return_value = mock_spotify_instance

        # 模拟artist_albums的返回值,无分页
        mock_spotify_instance.artist_albums.return_value = {
            'items': [
                {'name': 'Album 1'},
                {'name': 'Album 2'},
            ],
            'next': None
        }

        # 调用测试函数
        see_album('spotify:artist:2WX2uTcsvV5OnS0inACecP')
 
        # 验证artist_albums的调用参数是否正确
        mock_spotify_instance.artist_albums.assert_called_once_with(
            'spotify:artist:2WX2uTcsvV5OnS0inACecP', 
            album_type='album'
        )
        
        # 验证print函数的调用是否符合预期
        expected_print_calls = [
            call('Album 1'),
            call('Album 2'),
        ]
        mock_print.assert_has_calls(expected_print_calls, any_order=False)

if __name__ == '__main__':
    unittest.main()

验证结果

运行测试后,不会再调用实际Spotify API,测试会通过,且输出仅为测试框架的结果(无真实专辑列表与Mock专辑列表混合输出)。

内容的提问来源于stack exchange,提问作者LucaB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 14:02:48