Python测试中patch未触发:PyGithub模拟断言失败问题
解决PyGithub测试中
create_repo断言失败的问题 你遇到的问题核心是mock对象关联错误:业务代码里调用的organization.create_repo是get_organization返回的MagicMock对象的方法,和你patch的github.Organization.Organization.create_repo不是同一个,所以断言create_repo.assert_called()会失败。
修正后的测试代码
import unittest from unittest.mock import patch, MagicMock, ANY from github.Repository import Repository from src.github_service import GithubService class TestGithubService(unittest.TestCase): @patch('github.MainClass.Github.get_organization') def test_create_repo_returns_true(self, get_organization): # 创建模拟的Organization对象,给它添加create_repo方法 mock_org = MagicMock() mock_repo = MagicMock(spec=Repository) mock_org.create_repo.return_value = mock_repo # 让get_organization返回这个模拟的Organization get_organization.return_value = mock_org sut = GithubService("token") actual = sut.create_repo_extra('repo-name', 'description', 'organization-name', 'team-name') # 断言get_organization被正确调用 get_organization.assert_called_once_with('organization-name') # 断言create_repo被正确调用,参数匹配业务代码中的设置 mock_org.create_repo.assert_called_once_with( name='repo-name', description='description', private=True, has_issues=False, has_wiki=False, has_projects=False, allow_merge_commit=False ) self.assertTrue(actual)
关键改动说明
- 移除不必要的patch:不再patch
Organization.create_repo,而是直接控制get_organization返回的mock对象的行为,这样业务代码调用organization.create_repo时,就是调用我们定义的mock方法。 - 明确mock对象的关联:
get_organization返回的mock_org是手动创建的MagicMock,它的create_repo方法也是一个mock,可直接跟踪这个方法的调用情况。 - 更精准的断言:不仅断言方法被调用,还可验证调用参数是否符合预期,让测试更严谨。
另一种方案(保留patch类方法)
如果坚持要patchOrganization.create_repo,需要确保get_organization返回的是符合Organization规范的实例(而非嵌套的MagicMock),可以用spec参数创建:
import unittest from unittest.mock import patch, MagicMock, ANY from github.Organization import Organization from github.Repository import Repository from src.github_service import GithubService class TestGithubService(unittest.TestCase): @patch('github.Organization.Organization.create_repo') @patch('github.MainClass.Github.get_organization') def test_create_repo_returns_true(self, get_organization, create_repo): # 返回符合Organization规范的mock实例,这样patch的类方法会生效 mock_org = MagicMock(spec=Organization) get_organization.return_value = mock_org create_repo.return_value = MagicMock(spec=Repository) sut = GithubService("token") actual = sut.create_repo_extra('repo-name', 'description', 'organization-name', 'team-name') get_organization.assert_called_once_with('organization-name') create_repo.assert_called_once_with( name='repo-name', description='description', private=True, has_issues=False, has_wiki=False, has_projects=False, allow_merge_commit=False ) self.assertTrue(actual)
这个方案中,mock_org是基于Organization类的spec创建的mock,它的create_repo方法会被我们patch的Organization.create_repo替换,断言create_repo.assert_called()会生效。
内容的提问来源于stack exchange,提问作者Sparkmuse
相关产品推荐
相关产品推荐

