Add checking of unexpected calls and unexpected provided body to
RequestMockBuilder.
Reviewed in http://codereview.appspot.com/4996043/
diff --git a/apiclient/errors.py b/apiclient/errors.py
index beac5f4..c017912 100644
--- a/apiclient/errors.py
+++ b/apiclient/errors.py
@@ -70,10 +70,30 @@
"""Link type unknown or unexpected."""
pass
+
class UnacceptableMimeTypeError(Error):
"""That is an unacceptable mimetype for this operation."""
pass
+
class MediaUploadSizeError(Error):
"""Media is larger than the method can accept."""
pass
+
+
+class UnexpectedMethodError(Error):
+ """Exception raised by RequestMockBuilder on unexpected calls."""
+
+ def __init__(self, methodId=None):
+ """Constructor for an UnexpectedMethodError."""
+ super(UnexpectedMethodError, self).__init__(
+ 'Received unexpected call %s' % methodId)
+
+
+class UnexpectedBodyError(Error):
+ """Exception raised by RequestMockBuilder on unexpected bodies."""
+
+ def __init__(self, expected, provided):
+ """Constructor for an UnexpectedMethodError."""
+ super(UnexpectedBodyError, self).__init__(
+ 'Expected: [%s] - Provided: [%s]' % (expected, provided))
diff --git a/apiclient/http.py b/apiclient/http.py
index 5f4be00..081a4ed 100644
--- a/apiclient/http.py
+++ b/apiclient/http.py
@@ -30,6 +30,8 @@
from model import JsonModel
from errors import HttpError
+from errors import UnexpectedBodyError
+from errors import UnexpectedMethodError
from anyjson import simplejson
@@ -124,9 +126,11 @@
"""A simple mock of HttpRequest
Pass in a dictionary to the constructor that maps request methodIds to
- tuples of (httplib2.Response, content) that should be returned when that
- method is called. None may also be passed in for the httplib2.Response, in
- which case a 200 OK response will be generated.
+ tuples of (httplib2.Response, content, opt_expected_body) that should be
+ returned when that method is called. None may also be passed in for the
+ httplib2.Response, in which case a 200 OK response will be generated.
+ If an opt_expected_body (str or dict) is provided, it will be compared to
+ the body and UnexpectedBodyError will be raised on inequality.
Example:
response = '{"data": {"id": "tag:google.c...'
@@ -138,13 +142,14 @@
apiclient.discovery.build("buzz", "v1", requestBuilder=requestBuilder)
Methods that you do not supply a response for will return a
- 200 OK with an empty string as the response content. The methodId
- is taken from the rpcName in the discovery document.
+ 200 OK with an empty string as the response content or raise an excpetion if
+ check_unexpected is set to True. The methodId is taken from the rpcName
+ in the discovery document.
For more details see the project wiki.
"""
- def __init__(self, responses):
+ def __init__(self, responses, check_unexpected=False):
"""Constructor for RequestMockBuilder
The constructed object should be a callable object
@@ -154,8 +159,11 @@
of (httplib2.Response, content). The methodId
comes from the 'rpcName' field in the discovery
document.
+ check_unexpected - A boolean setting whether or not UnexpectedMethodError
+ should be raised on unsupplied method.
"""
self.responses = responses
+ self.check_unexpected = check_unexpected
def __call__(self, http, postproc, uri, method='GET', body=None,
headers=None, methodId=None):
@@ -165,8 +173,23 @@
parameters and the expected response.
"""
if methodId in self.responses:
- resp, content = self.responses[methodId]
+ response = self.responses[methodId]
+ resp, content = response[:2]
+ if len(response) > 2:
+ # Test the body against the supplied expected_body.
+ expected_body = response[2]
+ if bool(expected_body) != bool(body):
+ # Not expecting a body and provided one
+ # or expecting a body and not provided one.
+ raise UnexpectedBodyError(expected_body, body)
+ if isinstance(expected_body, str):
+ expected_body = simplejson.loads(expected_body)
+ body = simplejson.loads(body)
+ if body != expected_body:
+ raise UnexpectedBodyError(expected_body, body)
return HttpRequestMock(resp, content, postproc)
+ elif self.check_unexpected:
+ raise UnexpectedMethodError(methodId)
else:
model = JsonModel(False)
return HttpRequestMock(None, '{}', model.response)