my-Repository-Traffic프로젝트 이슈 - Python third-party mocking하기
😂 개요
프로젝트는 github API를 다른 Third-party
를 이용해서 호출하고 있었다.
유닛 테스트를 위해 테스트코드를 짜려다보니.. Third-party
API들은 어떻게 모킹하지?
의문이 들었다.
chatGPT
에게 물어봐서 해결하긴 했지만 그 과정을 적고 이해하기 위해 블로그에 적는다.
🔅 환경
1
2
3
4
5
6
7
8
9
10
11
12
def get_all_repositories_cloner(repositories: github.PaginatedList.PaginatedList) -> dict:
cloner_counts = {}
for repository in repositories:
clone_traffic = get_repository_clone_traffic(repository)
unique_cloner = clone_traffic['uniques']
if unique_cloner == 0:
continue
cloner_counts[repository.full_name] = unique_cloner
return cloner_counts
def get_repository_clone_traffic(repository: github.Repository.Repository) -> dict:
return repository.get_clones_traffic()
이 코드를 테스트해야한다.
get_all_repositories_cloner()
파라미터를 보면 github.PaginatedList.PaginatedList
라는 타입을 받는데, 이는 pygithub
라는 써드파티에서 제공하는 자료형이다.
for
문을 도는 부분이 있는데, 이 코드가 돌 수 있게 적절히 모킹해줘야한다.
또한 cloner_counts[repository.full_name]
에 repository.full_name
에 접근할 수 있도록 모킹해줘야한다.
그렇기에 repositories
라는 인자를 모킹해줘야하고, get_repository_clone_traffic()
모킹, for
문을 돌 수 있게 해야하고, .
연산자를 사용하기 위한 객체로 만들어야한다.
😊 방법
1
2
3
4
5
6
7
8
9
10
11
12
13
@pytest_asyncio.fixture
async def repositories() -> github.PaginatedList.PaginatedList:
class Repository:
def __init__(self, full_name):
self.full_name = full_name
mock_paginated_list = MagicMock(spec=github.PaginatedList.PaginatedList)
mock_paginated_list.__iter__.return_value = iter([
Repository(full_name="kkminseok.repo1"),
Repository(full_name="kkminseok.repo2"),
Repository(full_name="kkminseok.repo3"),
])
return mock_paginated_list
먼저, PaginatedList
자료형으로 반환해야하고, .
연산자를 사용하기 위해 클래스로 만들어서 리턴하도록 하였다.
그리고, for
문을 돌기 위해서 __iter__
를 모킹하였고, MagicMock
을 통해 자료형을 지정하였다.
실제 테스트 코드에서는
1
2
3
4
5
6
7
def test_get_all_repositories_cloner(repositories: github.PaginatedList.PaginatedList, mocker: MockerFixture):
mocker.patch("git_utils.get_repository_clone_traffic", return_value={"uniques": 100})
result = get_all_repositories_cloner(repositories)
assert len(result) == 3
assert result['kkminseok.repo1'] == 100
assert result['kkminseok.repo2'] == 100
assert result['kkminseok.repo3'] == 100
이렇게 호출해주면 된다.
막상 짜고나니 별 거 아닌데.. 은근 모킹하는데 오래 걸렸다.
This post is licensed under CC BY 4.0 by the author.