Skip to content

Commit e51909f

Browse files
feat: Add initial tests for account_management examples
This commit introduces a test structure and initial tests for several examples within the examples/account_management directory. All tests are written to use Google Ads API v19 and leverage unittest.mock for mocking API interactions. The following examples now have test coverage: - create_customer.py - get_account_hierarchy.py - get_change_details.py - get_change_summary.py - invite_user_with_access_role.py - link_manager_to_client.py - list_accessible_customers.py Each test suite typically covers: - Successful execution path and output verification. - GoogleAdsException handling. - Mocking of relevant Google Ads API services and client. Further tests for remaining files in this directory will be added in subsequent commits.
1 parent 2fa4823 commit e51909f

10 files changed

+1328
-0
lines changed

tests/examples/__init__.py

Whitespace-only changes.

tests/examples/account_management/.gitkeep

Whitespace-only changes.

tests/examples/account_management/__init__.py

Whitespace-only changes.
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import unittest
2+
from unittest.mock import patch, MagicMock
3+
4+
from google.ads.googleads.errors import GoogleAdsException
5+
# This import assumes that the test runner will add the root directory to sys.path
6+
# or that the `examples` directory is otherwise findable.
7+
from examples.account_management.create_customer import main
8+
9+
10+
class CreateCustomerTest(unittest.TestCase):
11+
12+
@patch("examples.account_management.create_customer.GoogleAdsClient.load_from_storage")
13+
def test_create_customer_success(self, mock_load_from_storage):
14+
"""Tests the successful creation of a customer."""
15+
# Create a mock GoogleAdsClient
16+
mock_google_ads_client = MagicMock()
17+
mock_load_from_storage.return_value = mock_google_ads_client
18+
19+
# Create a mock CustomerService
20+
mock_customer_service = MagicMock()
21+
mock_google_ads_client.get_service.return_value = mock_customer_service
22+
23+
# Mock the create_customer_client method to return a mock response object
24+
# This response object structure might need adjustment based on what the actual method returns
25+
# and what the main function does with it. For now, a simple MagicMock.
26+
mock_create_customer_response = MagicMock()
27+
mock_create_customer_response.resource_name = "customers/1234567890/customerClients/9876543210"
28+
mock_customer_service.create_customer_client.return_value = mock_create_customer_response
29+
30+
# Define test arguments
31+
manager_customer_id = "1234567890"
32+
currency_code = "USD"
33+
time_zone = "America/New_York"
34+
# The descriptive_name is optional in the script, so we'll test with it.
35+
descriptive_name = "Test Customer"
36+
37+
# Call the main function with test arguments
38+
# The original script takes client_customer_id as an argument, but it's not used.
39+
# The create_customer.py script expects:
40+
# main(client, manager_customer_id, currency_code, time_zone, descriptive_name=None)
41+
# We are mocking the client, so we pass the mock_google_ads_client
42+
main(
43+
mock_google_ads_client,
44+
manager_customer_id,
45+
currency_code,
46+
time_zone,
47+
descriptive_name,
48+
)
49+
50+
# Assert that get_service was called with the correct service name and version
51+
mock_google_ads_client.get_service.assert_called_once_with(
52+
"CustomerService", version="v19"
53+
)
54+
55+
# Assert that create_customer_client was called once with the correct parameters
56+
# The original script builds a CustomerClient object. We need to check the attributes
57+
# of the customer_client argument passed to create_customer_client.
58+
self.assertEqual(mock_customer_service.create_customer_client.call_count, 1)
59+
call_args = mock_customer_service.create_customer_client.call_args
60+
61+
# call_args is a tuple (args, kwargs). We expect (customer_id, customer_client, modify)
62+
# or (request=...) if using a request object.
63+
# The script uses: customer_service.create_customer_client(customer_id=manager_customer_id, customer_client=customer_client)
64+
self.assertEqual(call_args[1]['customer_id'], manager_customer_id)
65+
66+
# Check the customer_client object passed
67+
customer_client_arg = call_args[1]['customer_client']
68+
self.assertEqual(customer_client_arg.descriptive_name, descriptive_name)
69+
self.assertEqual(customer_client_arg.currency_code, currency_code)
70+
self.assertEqual(customer_client_arg.time_zone, time_zone)
71+
# The original script also sets client_customer.applied_labels, but only if an optional
72+
# "labels" argument is provided to main(). We are not testing that here.
73+
74+
75+
@patch("examples.account_management.create_customer.GoogleAdsClient.load_from_storage")
76+
def test_create_customer_google_ads_exception(self, mock_load_from_storage):
77+
"""Tests handling of GoogleAdsException during customer creation."""
78+
mock_google_ads_client = MagicMock()
79+
mock_load_from_storage.return_value = mock_google_ads_client
80+
81+
mock_customer_service = MagicMock()
82+
mock_google_ads_client.get_service.return_value = mock_customer_service
83+
84+
# Configure create_customer_client to raise GoogleAdsException
85+
# The exception needs to be instantiated with a failure object.
86+
# We can mock the failure object and its errors.
87+
mock_failure = MagicMock()
88+
mock_error = MagicMock()
89+
mock_error.message = "Test GoogleAdsException"
90+
mock_failure.errors = [mock_error]
91+
google_ads_exception = GoogleAdsException(
92+
mock_failure, "call", "trigger", "request_id", "error_code_enum"
93+
)
94+
mock_customer_service.create_customer_client.side_effect = google_ads_exception
95+
96+
manager_customer_id = "1234567890"
97+
currency_code = "USD"
98+
time_zone = "America/New_York"
99+
descriptive_name = "Test Customer Exception"
100+
101+
# We expect the main function to catch the GoogleAdsException and print an error message.
102+
# To verify this, we can check if sys.exit(1) is called, or if specific error logging occurs.
103+
# For simplicity, we'll assert that the exception is indeed raised and propagated
104+
# to the test if not caught, or if caught, that the program exits or logs.
105+
# The script's main function has a try-except block that prints the error and calls sys.exit(1).
106+
# We can mock sys.exit to check if it's called.
107+
with patch("sys.exit") as mock_sys_exit:
108+
main(
109+
mock_google_ads_client,
110+
manager_customer_id,
111+
currency_code,
112+
time_zone,
113+
descriptive_name,
114+
)
115+
# Assert that sys.exit was called, implying the exception was caught.
116+
mock_sys_exit.assert_called_once_with(1)
117+
118+
mock_google_ads_client.get_service.assert_called_once_with(
119+
"CustomerService", version="v19"
120+
)
121+
mock_customer_service.create_customer_client.assert_called_once()
122+
123+
124+
if __name__ == "__main__":
125+
unittest.main()

0 commit comments

Comments
 (0)