0

I would like to get all the GitHub branches of a certain repository. Using the GitHub API as documented here, https://developer.github.com/v3/repos/branches/#list-branches I try to use the GET request documented.

However, when I try unit testing, the response always evaluates to None and I get error: AttributeError: 'NoneType' object has no attribute 'json'. I am unsure if my issue is with the API call, or I am testing the call. See code below:

 @staticmethod
    def get_branches(git_base, org, repo):

        github_repo_url = f"https://{git_base}/api/v3/repos/{org}/{repo}"
        collected_all_branches: bool = False
        page = 1
        github_branches = []
        # collect all branches in repo
        while not collected_all_branches:
            response = (requests.get(f"{github_repo_url}/branches/?per_page=100&page={page}",
                                     headers=HEADERS))
            if len(response.json()) == 0:
                collected_all_branches = True
            else:
                github_branches.extend([response["name"] for response in response.json()])
            page = page + 1
        return github_branches

Unit Test:

    @patch.object(requests, "get", return_value=None)
    def test_get_branches(self, mock_get):

        r = GithubService.get_branches("test", "test", "test")
        mock_get.assert_called_with("test", "test", "test")

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
user19251203
  • 322
  • 4
  • 13
  • You have patched `requests.get` to return `None`, so in testing, `response` is `None`. You then attempt to access `response.json()`, which leads to the error you've shown. – larsks Aug 05 '22 at 13:31
  • @larsks after changing `return_value=Response`, I am getting error: `TypeError: json() missing 1 required positional argument: 'self'` at this line: `if len(response.json()) == 0:` – user19251203 Aug 05 '22 at 13:57

1 Answers1

0

The test is not set up correctly. Since the unit test verifies the arguments of the requests.get() call you can modify it like this:

    @patch("requests.get")
    def test_get_branches(self, mock_get):
        # Give the actual HEADERS you use in the get_branches() function call, for example something like:
        HEADERS = {"Accept": "application/vnd.github+json"}
        
        r = GithubService.get_branches("test", "test", "test")
        mock_get.assert_called_with("https://api.github.com/repos/test/test/branches/?per_page=100&page=1", headers=HEADERS)

The test will now pass successfully.

Also, the Github API call is incorrect. The documentation you have linked to says the URL must be of this format:

https://api.github.com/repos/OWNER/REPO/branches

So in get_branches() make the following change:

github_repo_url = f"https://api.github.com/repos/{org}/{repo}"
viggnah
  • 1,709
  • 1
  • 3
  • 12
  • after making changes:`return_value=Response`, I am getting error: `TypeError: json() missing 1 required positional argument: 'self'` at this line: `if len(response.json()) == 0:` which I am unsure how to resolve – user19251203 Aug 05 '22 at 14:00
  • @user19251203, I think you don't need to patch at all. Can you try after removing the `@patch.object(...)` line? – viggnah Aug 05 '22 at 14:16
  • without it I get: `TypeError: test_get_branches() missing 1 required positional argument: 'mock_get'` – user19251203 Aug 05 '22 at 14:18
  • @user19251203, sorry, I think I misunderstood the intention of your test. Have updated my answer, so that your test will work now. – viggnah Aug 06 '22 at 06:05