Skip to content
This repository was archived by the owner on Mar 6, 2026. It is now read-only.

Commit 78fec2c

Browse files
author
Jon Wayne Parrott
authored
Make testing style more consistent (#168)
Several overall style changes: 1. Avoid plain `Mock()` and `Mock(spec=thing)`., prefer `mock.create_autospec()`. 1. Don't `mock.patch` without `autospec`. 1. Don't give mock instances special names. Prefer `thing` over `thing_mock` and `mock_thing`. 1. When using `mock.patch`, use the same name as the item being patched to refer to the mock. ```python with mock.patch('module.thing') as thing: ... ``` and ``` @mock.patch('module.thing') def test(thing): ... ``` 1. Test helper factories should follow the naming convention `make_thing()`. 1. Use `ThingStub` when creating semi-functioning subclasses for testing purposes.
1 parent cf93481 commit 78fec2c

14 files changed

Lines changed: 377 additions & 328 deletions

tests/compute_engine/test__metadata.py

Lines changed: 56 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -24,191 +24,189 @@
2424
from google.auth import _helpers
2525
from google.auth import environment_vars
2626
from google.auth import exceptions
27+
from google.auth import transport
2728
from google.auth.compute_engine import _metadata
2829

2930
PATH = 'instance/service-accounts/default'
3031

3132

32-
@pytest.fixture
33-
def mock_request():
34-
request_mock = mock.Mock()
33+
def make_request(data, status=http_client.OK, headers=None):
34+
response = mock.create_autospec(transport.Response, instance=True)
35+
response.status = status
36+
response.data = _helpers.to_bytes(data)
37+
response.headers = headers or {}
3538

36-
def set_response(data, status=http_client.OK, headers=None):
37-
response = mock.Mock()
38-
response.status = status
39-
response.data = _helpers.to_bytes(data)
40-
response.headers = headers or {}
41-
request_mock.return_value = response
42-
return request_mock
39+
request = mock.create_autospec(transport.Request)
40+
request.return_value = response
4341

44-
yield set_response
42+
return request
4543

4644

47-
def test_ping_success(mock_request):
48-
request_mock = mock_request('', headers=_metadata._METADATA_HEADERS)
45+
def test_ping_success():
46+
request = make_request('', headers=_metadata._METADATA_HEADERS)
4947

50-
assert _metadata.ping(request_mock)
48+
assert _metadata.ping(request)
5149

52-
request_mock.assert_called_once_with(
50+
request.assert_called_once_with(
5351
method='GET',
5452
url=_metadata._METADATA_IP_ROOT,
5553
headers=_metadata._METADATA_HEADERS,
5654
timeout=_metadata._METADATA_DEFAULT_TIMEOUT)
5755

5856

59-
def test_ping_failure_bad_flavor(mock_request):
60-
request_mock = mock_request(
57+
def test_ping_failure_bad_flavor():
58+
request = make_request(
6159
'', headers={_metadata._METADATA_FLAVOR_HEADER: 'meep'})
6260

63-
assert not _metadata.ping(request_mock)
61+
assert not _metadata.ping(request)
6462

6563

66-
def test_ping_failure_connection_failed(mock_request):
67-
request_mock = mock_request('')
68-
request_mock.side_effect = exceptions.TransportError()
64+
def test_ping_failure_connection_failed():
65+
request = make_request('')
66+
request.side_effect = exceptions.TransportError()
6967

70-
assert not _metadata.ping(request_mock)
68+
assert not _metadata.ping(request)
7169

7270

73-
def test_ping_success_custom_root(mock_request):
74-
request_mock = mock_request('', headers=_metadata._METADATA_HEADERS)
71+
def test_ping_success_custom_root():
72+
request = make_request('', headers=_metadata._METADATA_HEADERS)
7573

7674
fake_ip = '1.2.3.4'
7775
os.environ[environment_vars.GCE_METADATA_IP] = fake_ip
7876
reload_module(_metadata)
7977

8078
try:
81-
assert _metadata.ping(request_mock)
79+
assert _metadata.ping(request)
8280
finally:
8381
del os.environ[environment_vars.GCE_METADATA_IP]
8482
reload_module(_metadata)
8583

86-
request_mock.assert_called_once_with(
84+
request.assert_called_once_with(
8785
method='GET',
8886
url='http://' + fake_ip,
8987
headers=_metadata._METADATA_HEADERS,
9088
timeout=_metadata._METADATA_DEFAULT_TIMEOUT)
9189

9290

93-
def test_get_success_json(mock_request):
91+
def test_get_success_json():
9492
key, value = 'foo', 'bar'
9593

9694
data = json.dumps({key: value})
97-
request_mock = mock_request(
95+
request = make_request(
9896
data, headers={'content-type': 'application/json'})
9997

100-
result = _metadata.get(request_mock, PATH)
98+
result = _metadata.get(request, PATH)
10199

102-
request_mock.assert_called_once_with(
100+
request.assert_called_once_with(
103101
method='GET',
104102
url=_metadata._METADATA_ROOT + PATH,
105103
headers=_metadata._METADATA_HEADERS)
106104
assert result[key] == value
107105

108106

109-
def test_get_success_text(mock_request):
107+
def test_get_success_text():
110108
data = 'foobar'
111-
request_mock = mock_request(data, headers={'content-type': 'text/plain'})
109+
request = make_request(data, headers={'content-type': 'text/plain'})
112110

113-
result = _metadata.get(request_mock, PATH)
111+
result = _metadata.get(request, PATH)
114112

115-
request_mock.assert_called_once_with(
113+
request.assert_called_once_with(
116114
method='GET',
117115
url=_metadata._METADATA_ROOT + PATH,
118116
headers=_metadata._METADATA_HEADERS)
119117
assert result == data
120118

121119

122-
def test_get_success_custom_root(mock_request):
123-
request_mock = mock_request(
120+
def test_get_success_custom_root():
121+
request = make_request(
124122
'{}', headers={'content-type': 'application/json'})
125123

126124
fake_root = 'another.metadata.service'
127125
os.environ[environment_vars.GCE_METADATA_ROOT] = fake_root
128126
reload_module(_metadata)
129127

130128
try:
131-
_metadata.get(request_mock, PATH)
129+
_metadata.get(request, PATH)
132130
finally:
133131
del os.environ[environment_vars.GCE_METADATA_ROOT]
134132
reload_module(_metadata)
135133

136-
request_mock.assert_called_once_with(
134+
request.assert_called_once_with(
137135
method='GET',
138136
url='http://{}/computeMetadata/v1/{}'.format(fake_root, PATH),
139137
headers=_metadata._METADATA_HEADERS)
140138

141139

142-
def test_get_failure(mock_request):
143-
request_mock = mock_request(
140+
def test_get_failure():
141+
request = make_request(
144142
'Metadata error', status=http_client.NOT_FOUND)
145143

146144
with pytest.raises(exceptions.TransportError) as excinfo:
147-
_metadata.get(request_mock, PATH)
145+
_metadata.get(request, PATH)
148146

149147
assert excinfo.match(r'Metadata error')
150148

151-
request_mock.assert_called_once_with(
149+
request.assert_called_once_with(
152150
method='GET',
153151
url=_metadata._METADATA_ROOT + PATH,
154152
headers=_metadata._METADATA_HEADERS)
155153

156154

157-
def test_get_failure_bad_json(mock_request):
158-
request_mock = mock_request(
155+
def test_get_failure_bad_json():
156+
request = make_request(
159157
'{', headers={'content-type': 'application/json'})
160158

161159
with pytest.raises(exceptions.TransportError) as excinfo:
162-
_metadata.get(request_mock, PATH)
160+
_metadata.get(request, PATH)
163161

164162
assert excinfo.match(r'invalid JSON')
165163

166-
request_mock.assert_called_once_with(
164+
request.assert_called_once_with(
167165
method='GET',
168166
url=_metadata._METADATA_ROOT + PATH,
169167
headers=_metadata._METADATA_HEADERS)
170168

171169

172-
def test_get_project_id(mock_request):
170+
def test_get_project_id():
173171
project = 'example-project'
174-
request_mock = mock_request(
172+
request = make_request(
175173
project, headers={'content-type': 'text/plain'})
176174

177-
project_id = _metadata.get_project_id(request_mock)
175+
project_id = _metadata.get_project_id(request)
178176

179-
request_mock.assert_called_once_with(
177+
request.assert_called_once_with(
180178
method='GET',
181179
url=_metadata._METADATA_ROOT + 'project/project-id',
182180
headers=_metadata._METADATA_HEADERS)
183181
assert project_id == project
184182

185183

186184
@mock.patch('google.auth._helpers.utcnow', return_value=datetime.datetime.min)
187-
def test_get_service_account_token(utcnow, mock_request):
185+
def test_get_service_account_token(utcnow):
188186
ttl = 500
189-
request_mock = mock_request(
187+
request = make_request(
190188
json.dumps({'access_token': 'token', 'expires_in': ttl}),
191189
headers={'content-type': 'application/json'})
192190

193-
token, expiry = _metadata.get_service_account_token(request_mock)
191+
token, expiry = _metadata.get_service_account_token(request)
194192

195-
request_mock.assert_called_once_with(
193+
request.assert_called_once_with(
196194
method='GET',
197195
url=_metadata._METADATA_ROOT + PATH + '/token',
198196
headers=_metadata._METADATA_HEADERS)
199197
assert token == 'token'
200198
assert expiry == utcnow() + datetime.timedelta(seconds=ttl)
201199

202200

203-
def test_get_service_account_info(mock_request):
201+
def test_get_service_account_info():
204202
key, value = 'foo', 'bar'
205-
request_mock = mock_request(
203+
request = make_request(
206204
json.dumps({key: value}),
207205
headers={'content-type': 'application/json'})
208206

209-
info = _metadata.get_service_account_info(request_mock)
207+
info = _metadata.get_service_account_info(request)
210208

211-
request_mock.assert_called_once_with(
209+
request.assert_called_once_with(
212210
method='GET',
213211
url=_metadata._METADATA_ROOT + PATH + '/?recursive=true',
214212
headers=_metadata._METADATA_HEADERS)

tests/compute_engine/test_credentials.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
from google.auth import _helpers
2121
from google.auth import exceptions
22+
from google.auth import transport
2223
from google.auth.compute_engine import credentials
2324

2425

@@ -41,9 +42,9 @@ def test_default_state(self):
4142
@mock.patch(
4243
'google.auth._helpers.utcnow',
4344
return_value=datetime.datetime.min + _helpers.CLOCK_SKEW)
44-
@mock.patch('google.auth.compute_engine._metadata.get')
45-
def test_refresh_success(self, get_mock, now_mock):
46-
get_mock.side_effect = [{
45+
@mock.patch('google.auth.compute_engine._metadata.get', autospec=True)
46+
def test_refresh_success(self, get, utcnow):
47+
get.side_effect = [{
4748
# First request is for sevice account info.
4849
'email': 'service-account@example.com',
4950
'scopes': ['one', 'two']
@@ -59,7 +60,7 @@ def test_refresh_success(self, get_mock, now_mock):
5960
# Check that the credentials have the token and proper expiration
6061
assert self.credentials.token == 'token'
6162
assert self.credentials.expiry == (
62-
now_mock() + datetime.timedelta(seconds=500))
63+
utcnow() + datetime.timedelta(seconds=500))
6364

6465
# Check the credential info
6566
assert (self.credentials.service_account_email ==
@@ -71,17 +72,17 @@ def test_refresh_success(self, get_mock, now_mock):
7172
assert self.credentials.valid
7273

7374
@mock.patch('google.auth.compute_engine._metadata.get', autospec=True)
74-
def test_refresh_error(self, get_mock):
75-
get_mock.side_effect = exceptions.TransportError('http error')
75+
def test_refresh_error(self, get):
76+
get.side_effect = exceptions.TransportError('http error')
7677

7778
with pytest.raises(exceptions.RefreshError) as excinfo:
7879
self.credentials.refresh(None)
7980

8081
assert excinfo.match(r'http error')
8182

8283
@mock.patch('google.auth.compute_engine._metadata.get', autospec=True)
83-
def test_before_request_refreshes(self, get_mock):
84-
get_mock.side_effect = [{
84+
def test_before_request_refreshes(self, get):
85+
get.side_effect = [{
8586
# First request is for sevice account info.
8687
'email': 'service-account@example.com',
8788
'scopes': 'one two'
@@ -95,11 +96,12 @@ def test_before_request_refreshes(self, get_mock):
9596
assert not self.credentials.valid
9697

9798
# before_request should cause a refresh
99+
request = mock.create_autospec(transport.Request, instance=True)
98100
self.credentials.before_request(
99-
mock.Mock(), 'GET', 'http://example.com?a=1#3', {})
101+
request, 'GET', 'http://example.com?a=1#3', {})
100102

101103
# The refresh endpoint should've been called.
102-
assert get_mock.called
104+
assert get.called
103105

104106
# Credentials should now be valid.
105107
assert self.credentials.valid

0 commit comments

Comments
 (0)