How to mock googleapiclient.discovery.build to unit test reading from google sheets

Viewed 624

Hi I want to unit test the below code by mocking the api calls .

def get_data_from_google_sheets(spreadsheet_id, google_creds):
    """
    Pupose:
    """
    scopes = ['https://www.googleapis.com/auth/sqlservice.admin','https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive']
    range_name = 'A1:AA1000'

  

    credentials = service_account.Credentials.from_service_account_info(google_creds, scopes = scopes)
    
    service = build('sheets', 'v4', credentials = credentials)
    
    sheet = service.spreadsheets()
 

    result_from_sheet = sheet.values().get(spreadsheetId = spreadsheet_id,range = range_name).execute()

    rows = result_from_sheet['values'][1:]
 
    return rows

I have tried using the below code

def test_get_data(mocker):
    sheet_id = "123"
    creds = {"b":"d"}
    mocker.patch.object(
        google.oauth2.service_account.Credentials,'from_service_account_info',
        return_value = ""
    )

    mocker.patch.object(
        googleapiclient.discovery.build.return_value.spreadsheets.return_value.values.return_value.get.return_value,'execute',
        return_value = []
    )

    result = get_data_from_google_sheets(sheet_id, creds)
    assert len(result) == 0

Getting error - AttributeError: 'function' object has no attribute 'return_value'

1 Answers

You can use unittest.mock.patch to patch google.oauth2.service_account module and googleapiclient.discovery.build function.

E.g.

example.py:

from google.oauth2 import service_account
from googleapiclient.discovery import build

def get_data_from_google_sheets(spreadsheet_id, google_creds):
    scopes = ['https://www.googleapis.com/auth/sqlservice.admin','https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive']
    range_name = 'A1:AA1000'
    credentials = service_account.Credentials.from_service_account_info(google_creds, scopes = scopes)
    service = build('sheets', 'v4', credentials = credentials)
    sheet = service.spreadsheets()
    result_from_sheet = sheet.values().get(spreadsheetId = spreadsheet_id,range = range_name).execute()
    rows = result_from_sheet['values'][1:]
    return rows

test_example.py:

from unittest import TestCase
import unittest
from unittest.mock import Mock, patch
from example import get_data_from_google_sheets


class TestExample(TestCase):
    @patch('example.build')
    @patch('example.service_account.Credentials')
    def test_get_data(self, mock_service_acount_credentials, mock_build):
        sheet_id = "123"
        creds = {"b": "d"}
        mock_service_acount_credentials.from_service_account_info.return_value = '123'
        mock_build.return_value.spreadsheets.return_value.values.return_value.get.return_value.execute.return_value = {
            'values': []}
        result = get_data_from_google_sheets(sheet_id, creds)
        self.assertEqual(len(result), 0)


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

Test result:

.
----------------------------------------------------------------------
Ran 1 test in 0.004s

OK
Name                                         Stmts   Miss  Cover   Missing
--------------------------------------------------------------------------
src/stackoverflow/70791609/example.py           11      0   100%
src/stackoverflow/70791609/test_example.py      16      0   100%
--------------------------------------------------------------------------
TOTAL                                           27      0   100%
Related