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.
diff --git a/tests/oauth2/test__client.py b/tests/oauth2/test__client.py
index 8c19c3e..6aeb3d1 100644
--- a/tests/oauth2/test__client.py
+++ b/tests/oauth2/test__client.py
@@ -22,6 +22,7 @@
from six.moves import urllib
from google.auth import exceptions
+from google.auth import transport
from google.oauth2 import _client
@@ -46,7 +47,7 @@
@mock.patch('google.auth._helpers.utcnow', return_value=datetime.datetime.min)
-def test__parse_expiry(now_mock):
+def test__parse_expiry(unused_utcnow):
result = _client._parse_expiry({'expires_in': 500})
assert result == datetime.datetime.min + datetime.timedelta(seconds=500)
@@ -55,15 +56,17 @@
assert _client._parse_expiry({}) is None
-def _make_request(response_data):
- response = mock.Mock()
- response.status = http_client.OK
+def make_request(response_data, status=http_client.OK):
+ response = mock.create_autospec(transport.Response, instance=True)
+ response.status = status
response.data = json.dumps(response_data).encode('utf-8')
- return mock.Mock(return_value=response)
+ request = mock.create_autospec(transport.Request)
+ request.return_value = response
+ return request
def test__token_endpoint_request():
- request = _make_request({'test': 'response'})
+ request = make_request({'test': 'response'})
result = _client._token_endpoint_request(
request, 'http://example.com', {'test': 'params'})
@@ -80,16 +83,13 @@
def test__token_endpoint_request_error():
- response = mock.Mock()
- response.status = http_client.BAD_REQUEST
- response.data = b'Error'
- request = mock.Mock(return_value=response)
+ request = make_request({}, status=http_client.BAD_REQUEST)
with pytest.raises(exceptions.RefreshError):
_client._token_endpoint_request(request, 'http://example.com', {})
-def _verify_request_params(request, params):
+def verify_request_params(request, params):
request_body = request.call_args[1]['body']
request_params = urllib.parse.parse_qs(request_body)
@@ -98,8 +98,8 @@
@mock.patch('google.auth._helpers.utcnow', return_value=datetime.datetime.min)
-def test_jwt_grant(now_mock):
- request = _make_request({
+def test_jwt_grant(utcnow):
+ request = make_request({
'access_token': 'token',
'expires_in': 500,
'extra': 'data'})
@@ -108,19 +108,19 @@
request, 'http://example.com', 'assertion_value')
# Check request call
- _verify_request_params(request, {
+ verify_request_params(request, {
'grant_type': _client._JWT_GRANT_TYPE,
'assertion': 'assertion_value'
})
# Check result
assert token == 'token'
- assert expiry == datetime.datetime.min + datetime.timedelta(seconds=500)
+ assert expiry == utcnow() + datetime.timedelta(seconds=500)
assert extra_data['extra'] == 'data'
def test_jwt_grant_no_access_token():
- request = _make_request({
+ request = make_request({
# No access token.
'expires_in': 500,
'extra': 'data'})
@@ -130,8 +130,8 @@
@mock.patch('google.auth._helpers.utcnow', return_value=datetime.datetime.min)
-def test_refresh_grant(now_mock):
- request = _make_request({
+def test_refresh_grant(unused_utcnow):
+ request = make_request({
'access_token': 'token',
'refresh_token': 'new_refresh_token',
'expires_in': 500,
@@ -142,7 +142,7 @@
'client_secret')
# Check request call
- _verify_request_params(request, {
+ verify_request_params(request, {
'grant_type': _client._REFRESH_GRANT_TYPE,
'refresh_token': 'refresh_token',
'client_id': 'client_id',
@@ -157,7 +157,7 @@
def test_refresh_grant_no_access_token():
- request = _make_request({
+ request = make_request({
# No access token.
'refresh_token': 'new_refresh_token',
'expires_in': 500,
diff --git a/tests/oauth2/test_credentials.py b/tests/oauth2/test_credentials.py
index e15766a..14984a1 100644
--- a/tests/oauth2/test_credentials.py
+++ b/tests/oauth2/test_credentials.py
@@ -18,6 +18,7 @@
import pytest
from google.auth import _helpers
+from google.auth import transport
from google.oauth2 import credentials
@@ -26,40 +27,41 @@
REFRESH_TOKEN = 'refresh_token'
CLIENT_ID = 'client_id'
CLIENT_SECRET = 'client_secret'
- credentials = None
- @pytest.fixture(autouse=True)
- def credentials_fixture(self):
- self.credentials = credentials.Credentials(
- token=None, refresh_token=self.REFRESH_TOKEN,
- token_uri=self.TOKEN_URI, client_id=self.CLIENT_ID,
- client_secret=self.CLIENT_SECRET)
+ @classmethod
+ def make_credentials(cls):
+ return credentials.Credentials(
+ token=None, refresh_token=cls.REFRESH_TOKEN,
+ token_uri=cls.TOKEN_URI, client_id=cls.CLIENT_ID,
+ client_secret=cls.CLIENT_SECRET)
def test_default_state(self):
- assert not self.credentials.valid
+ credentials = self.make_credentials()
+ assert not credentials.valid
# Expiration hasn't been set yet
- assert not self.credentials.expired
+ assert not credentials.expired
# Scopes aren't required for these credentials
- assert not self.credentials.requires_scopes
+ assert not credentials.requires_scopes
# Test properties
- assert self.credentials.refresh_token == self.REFRESH_TOKEN
- assert self.credentials.token_uri == self.TOKEN_URI
- assert self.credentials.client_id == self.CLIENT_ID
- assert self.credentials.client_secret == self.CLIENT_SECRET
+ assert credentials.refresh_token == self.REFRESH_TOKEN
+ assert credentials.token_uri == self.TOKEN_URI
+ assert credentials.client_id == self.CLIENT_ID
+ assert credentials.client_secret == self.CLIENT_SECRET
def test_create_scoped(self):
+ credentials = self.make_credentials()
with pytest.raises(NotImplementedError):
- self.credentials.with_scopes(['email'])
+ credentials.with_scopes(['email'])
@mock.patch('google.oauth2._client.refresh_grant', autospec=True)
@mock.patch(
'google.auth._helpers.utcnow',
return_value=datetime.datetime.min + _helpers.CLOCK_SKEW)
- def test_refresh_success(self, now_mock, refresh_grant_mock):
+ def test_refresh_success(self, unused_utcnow, refresh_grant):
token = 'token'
expiry = _helpers.utcnow() + datetime.timedelta(seconds=500)
grant_response = {'id_token': mock.sentinel.id_token}
- refresh_grant_mock.return_value = (
+ refresh_grant.return_value = (
# Access token
token,
# New refresh token
@@ -68,21 +70,23 @@
expiry,
# Extra data
grant_response)
- request_mock = mock.Mock()
+
+ request = mock.create_autospec(transport.Request)
+ credentials = self.make_credentials()
# Refresh credentials
- self.credentials.refresh(request_mock)
+ credentials.refresh(request)
# Check jwt grant call.
- refresh_grant_mock.assert_called_with(
- request_mock, self.TOKEN_URI, self.REFRESH_TOKEN, self.CLIENT_ID,
+ refresh_grant.assert_called_with(
+ request, self.TOKEN_URI, self.REFRESH_TOKEN, self.CLIENT_ID,
self.CLIENT_SECRET)
# Check that the credentials have the token and expiry
- assert self.credentials.token == token
- assert self.credentials.expiry == expiry
- assert self.credentials.id_token == mock.sentinel.id_token
+ assert credentials.token == token
+ assert credentials.expiry == expiry
+ assert credentials.id_token == mock.sentinel.id_token
# Check that the credentials are valid (have a token and are not
# expired)
- assert self.credentials.valid
+ assert credentials.valid
diff --git a/tests/oauth2/test_id_token.py b/tests/oauth2/test_id_token.py
index 7f89547..360f92f 100644
--- a/tests/oauth2/test_id_token.py
+++ b/tests/oauth2/test_id_token.py
@@ -18,18 +18,20 @@
import pytest
from google.auth import exceptions
-import google.auth.transport
+from google.auth import transport
from google.oauth2 import id_token
def make_request(status, data=None):
- response = mock.Mock()
+ response = mock.create_autospec(transport.Response, instance=True)
response.status = status
if data is not None:
response.data = json.dumps(data).encode('utf-8')
- return mock.Mock(return_value=response, spec=google.auth.transport.Request)
+ request = mock.create_autospec(transport.Request)
+ request.return_value = response
+ return request
def test__fetch_certs_success():
diff --git a/tests/oauth2/test_service_account.py b/tests/oauth2/test_service_account.py
index e80b7d4..94bd7f4 100644
--- a/tests/oauth2/test_service_account.py
+++ b/tests/oauth2/test_service_account.py
@@ -17,11 +17,11 @@
import os
import mock
-import pytest
from google.auth import _helpers
from google.auth import crypt
from google.auth import jwt
+from google.auth import transport
from google.oauth2 import service_account
@@ -41,21 +41,17 @@
with open(SERVICE_ACCOUNT_JSON_FILE, 'r') as fh:
SERVICE_ACCOUNT_INFO = json.load(fh)
-
-@pytest.fixture(scope='module')
-def signer():
- return crypt.RSASigner.from_string(PRIVATE_KEY_BYTES, '1')
+SIGNER = crypt.RSASigner.from_string(PRIVATE_KEY_BYTES, '1')
class TestCredentials(object):
SERVICE_ACCOUNT_EMAIL = 'service-account@example.com'
TOKEN_URI = 'https://example.com/oauth2/token'
- credentials = None
- @pytest.fixture(autouse=True)
- def credentials_fixture(self, signer):
- self.credentials = service_account.Credentials(
- signer, self.SERVICE_ACCOUNT_EMAIL, self.TOKEN_URI)
+ @classmethod
+ def make_credentials(cls):
+ return service_account.Credentials(
+ SIGNER, cls.SERVICE_ACCOUNT_EMAIL, cls.TOKEN_URI)
def test_from_service_account_info(self):
credentials = service_account.Credentials.from_service_account_info(
@@ -112,96 +108,108 @@
assert credentials._additional_claims == additional_claims
def test_default_state(self):
- assert not self.credentials.valid
+ credentials = self.make_credentials()
+ assert not credentials.valid
# Expiration hasn't been set yet
- assert not self.credentials.expired
+ assert not credentials.expired
# Scopes haven't been specified yet
- assert self.credentials.requires_scopes
+ assert credentials.requires_scopes
def test_sign_bytes(self):
+ credentials = self.make_credentials()
to_sign = b'123'
- signature = self.credentials.sign_bytes(to_sign)
+ signature = credentials.sign_bytes(to_sign)
assert crypt.verify_signature(to_sign, signature, PUBLIC_CERT_BYTES)
def test_signer(self):
- assert isinstance(self.credentials.signer, crypt.Signer)
+ credentials = self.make_credentials()
+ assert isinstance(credentials.signer, crypt.Signer)
def test_signer_email(self):
- assert self.credentials.signer_email == self.SERVICE_ACCOUNT_EMAIL
+ credentials = self.make_credentials()
+ assert credentials.signer_email == self.SERVICE_ACCOUNT_EMAIL
def test_create_scoped(self):
+ credentials = self.make_credentials()
scopes = ['email', 'profile']
- credentials = self.credentials.with_scopes(scopes)
+ credentials = credentials.with_scopes(scopes)
assert credentials._scopes == scopes
def test_with_claims(self):
- new_credentials = self.credentials.with_claims({'meep': 'moop'})
+ credentials = self.make_credentials()
+ new_credentials = credentials.with_claims({'meep': 'moop'})
assert new_credentials._additional_claims == {'meep': 'moop'}
def test__make_authorization_grant_assertion(self):
- token = self.credentials._make_authorization_grant_assertion()
+ credentials = self.make_credentials()
+ token = credentials._make_authorization_grant_assertion()
payload = jwt.decode(token, PUBLIC_CERT_BYTES)
assert payload['iss'] == self.SERVICE_ACCOUNT_EMAIL
assert payload['aud'] == self.TOKEN_URI
def test__make_authorization_grant_assertion_scoped(self):
+ credentials = self.make_credentials()
scopes = ['email', 'profile']
- credentials = self.credentials.with_scopes(scopes)
+ credentials = credentials.with_scopes(scopes)
token = credentials._make_authorization_grant_assertion()
payload = jwt.decode(token, PUBLIC_CERT_BYTES)
assert payload['scope'] == 'email profile'
def test__make_authorization_grant_assertion_subject(self):
+ credentials = self.make_credentials()
subject = 'user@example.com'
- credentials = self.credentials.with_subject(subject)
+ credentials = credentials.with_subject(subject)
token = credentials._make_authorization_grant_assertion()
payload = jwt.decode(token, PUBLIC_CERT_BYTES)
assert payload['sub'] == subject
@mock.patch('google.oauth2._client.jwt_grant', autospec=True)
- def test_refresh_success(self, jwt_grant_mock):
+ def test_refresh_success(self, jwt_grant):
+ credentials = self.make_credentials()
token = 'token'
- jwt_grant_mock.return_value = (
+ jwt_grant.return_value = (
token,
_helpers.utcnow() + datetime.timedelta(seconds=500),
{})
- request_mock = mock.Mock()
+ request = mock.create_autospec(transport.Request, instance=True)
# Refresh credentials
- self.credentials.refresh(request_mock)
+ credentials.refresh(request)
# Check jwt grant call.
- assert jwt_grant_mock.called
- request, token_uri, assertion = jwt_grant_mock.call_args[0]
- assert request == request_mock
- assert token_uri == self.credentials._token_uri
+ assert jwt_grant.called
+
+ called_request, token_uri, assertion = jwt_grant.call_args[0]
+ assert called_request == request
+ assert token_uri == credentials._token_uri
assert jwt.decode(assertion, PUBLIC_CERT_BYTES)
# No further assertion done on the token, as there are separate tests
# for checking the authorization grant assertion.
# Check that the credentials have the token.
- assert self.credentials.token == token
+ assert credentials.token == token
# Check that the credentials are valid (have a token and are not
# expired)
- assert self.credentials.valid
+ assert credentials.valid
@mock.patch('google.oauth2._client.jwt_grant', autospec=True)
- def test_before_request_refreshes(self, jwt_grant_mock):
+ def test_before_request_refreshes(self, jwt_grant):
+ credentials = self.make_credentials()
token = 'token'
- jwt_grant_mock.return_value = (
+ jwt_grant.return_value = (
token, _helpers.utcnow() + datetime.timedelta(seconds=500), None)
- request_mock = mock.Mock()
+ request = mock.create_autospec(transport.Request, instance=True)
# Credentials should start as invalid
- assert not self.credentials.valid
+ assert not credentials.valid
# before_request should cause a refresh
- self.credentials.before_request(
- request_mock, 'GET', 'http://example.com?a=1#3', {})
+ credentials.before_request(
+ request, 'GET', 'http://example.com?a=1#3', {})
# The refresh endpoint should've been called.
- assert jwt_grant_mock.called
+ assert jwt_grant.called
# Credentials should now be valid.
- assert self.credentials.valid
+ assert credentials.valid