mirror of
https://github.com/gsi-upm/senpy
synced 2024-11-22 00:02:28 +00:00
Add *responses* to improve mocking
This commit is contained in:
parent
a3eb8f196c
commit
7c7a815d1a
@ -10,5 +10,6 @@ PyYAML
|
||||
rdflib
|
||||
rdflib-jsonld
|
||||
numpy
|
||||
scipy
|
||||
scip
|
||||
scikit-learn
|
||||
responses
|
||||
|
@ -24,7 +24,7 @@ class Client(object):
|
||||
return {d.name: d for d in resp}
|
||||
|
||||
def request(self, path=None, method='GET', **params):
|
||||
url = '{}{}'.format(self.endpoint, path)
|
||||
url = '{}{}'.format(self.endpoint.rstrip('/'), path)
|
||||
response = requests.request(method=method, url=url, params=params)
|
||||
try:
|
||||
resp = models.from_dict(response.json())
|
||||
|
@ -24,6 +24,7 @@ import nltk
|
||||
from .. import models, utils
|
||||
from .. import api
|
||||
from .. import gsitk_compat
|
||||
from .. import testing
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@ -143,14 +144,23 @@ class Plugin(with_metaclass(PluginMeta, models.Plugin)):
|
||||
self.log.warn('Test case failed:\n{}'.format(pprint.pformat(case)))
|
||||
raise
|
||||
|
||||
def test_case(self, case):
|
||||
def test_case(self, case, mock=testing.MOCK_REQUESTS):
|
||||
entry = models.Entry(case['entry'])
|
||||
given_parameters = case.get('params', case.get('parameters', {}))
|
||||
expected = case.get('expected', None)
|
||||
should_fail = case.get('should_fail', False)
|
||||
responses = case.get('responses', [])
|
||||
|
||||
try:
|
||||
params = api.parse_params(given_parameters, self.extra_params)
|
||||
res = list(self.analyse_entries([entry, ], params))
|
||||
|
||||
method = partial(self.analyse_entries, [entry, ], params)
|
||||
|
||||
if mock:
|
||||
res = list(method())
|
||||
else:
|
||||
with testing.patch_all_requests(responses):
|
||||
res = list(method())
|
||||
|
||||
if not isinstance(expected, list):
|
||||
expected = [expected]
|
||||
|
@ -4,6 +4,8 @@ import json
|
||||
from senpy.plugins import SentimentPlugin
|
||||
from senpy.models import Sentiment
|
||||
|
||||
ENDPOINT = 'http://www.sentiment140.com/api/bulkClassifyJson'
|
||||
|
||||
|
||||
class Sentiment140(SentimentPlugin):
|
||||
'''Connects to the sentiment140 free API: http://sentiment140.com'''
|
||||
@ -26,7 +28,7 @@ class Sentiment140(SentimentPlugin):
|
||||
|
||||
def analyse_entry(self, entry, params):
|
||||
lang = params["language"]
|
||||
res = requests.post("http://www.sentiment140.com/api/bulkClassifyJson",
|
||||
res = requests.post(ENDPOINT,
|
||||
json.dumps({
|
||||
"language": lang,
|
||||
"data": [{
|
||||
@ -52,18 +54,6 @@ class Sentiment140(SentimentPlugin):
|
||||
entry.language = lang
|
||||
yield entry
|
||||
|
||||
def test(self, *args, **kwargs):
|
||||
'''
|
||||
To avoid calling the sentiment140 API, we will mock the results
|
||||
from requests.
|
||||
'''
|
||||
from senpy.testing import patch_requests
|
||||
expected = {"data": [{"polarity": 4}]}
|
||||
with patch_requests(expected) as (request, response):
|
||||
super(Sentiment140, self).test(*args, **kwargs)
|
||||
assert request.called
|
||||
assert response.json.called
|
||||
|
||||
test_cases = [
|
||||
{
|
||||
'entry': {
|
||||
@ -77,6 +67,9 @@ class Sentiment140(SentimentPlugin):
|
||||
'marl:hasPolarity': 'marl:Positive',
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
'responses': [{'url': ENDPOINT,
|
||||
'method': 'POST',
|
||||
'json': {'data': [{'polarity': 4}]}}]
|
||||
}
|
||||
]
|
||||
|
@ -1,36 +1,31 @@
|
||||
try:
|
||||
from unittest.mock import patch, MagicMock
|
||||
except ImportError:
|
||||
from mock import patch, MagicMock
|
||||
|
||||
from past.builtins import basestring
|
||||
|
||||
|
||||
import json
|
||||
from contextlib import contextmanager
|
||||
import os
|
||||
import responses as requestmock
|
||||
|
||||
from .models import BaseModel
|
||||
|
||||
|
||||
@contextmanager
|
||||
def patch_requests(value, code=200):
|
||||
success = MagicMock()
|
||||
if isinstance(value, BaseModel):
|
||||
value = value.jsonld()
|
||||
if not isinstance(value, basestring):
|
||||
data = json.dumps(value)
|
||||
MOCK_REQUESTS = os.environ.get('MOCK_REQUESTS', '').lower() in ['no', 'false']
|
||||
|
||||
|
||||
def patch_all_requests(responses):
|
||||
|
||||
patched = requestmock.RequestsMock()
|
||||
|
||||
for response in responses or []:
|
||||
args = response.copy()
|
||||
if 'json' in args and isinstance(args['json'], BaseModel):
|
||||
args['json'] = args['json'].jsonld()
|
||||
args['method'] = getattr(requestmock, args.get('method', 'GET'))
|
||||
patched.add(**args)
|
||||
return patched
|
||||
|
||||
|
||||
def patch_requests(url, response, method='GET', status=200):
|
||||
args = {'url': url, 'method': method, 'status': status}
|
||||
if isinstance(response, basestring):
|
||||
args['body'] = response
|
||||
else:
|
||||
data = value
|
||||
|
||||
success.json.return_value = value
|
||||
|
||||
success.status_code = code
|
||||
success.content = data
|
||||
success.text = data
|
||||
|
||||
method_mocker = MagicMock()
|
||||
method_mocker.return_value = success
|
||||
with patch.multiple('requests', request=method_mocker,
|
||||
get=method_mocker, post=method_mocker):
|
||||
yield method_mocker, success
|
||||
assert method_mocker.called
|
||||
args['json'] = response
|
||||
return patch_all_requests([args])
|
||||
|
@ -14,22 +14,15 @@ class ModelsTest(TestCase):
|
||||
def test_client(self):
|
||||
endpoint = 'http://dummy/'
|
||||
client = Client(endpoint)
|
||||
with patch_requests(Results()) as (request, response):
|
||||
with patch_requests('http://dummy/', Results()):
|
||||
resp = client.analyse('hello')
|
||||
assert isinstance(resp, Results)
|
||||
request.assert_called_with(
|
||||
url=endpoint + '/', method='GET', params={'input': 'hello'})
|
||||
with patch_requests(Error('Nothing')) as (request, response):
|
||||
with patch_requests('http://dummy/', Error('Nothing')):
|
||||
try:
|
||||
client.analyse(input='hello', algorithm='NONEXISTENT')
|
||||
raise Exception('Exceptions should be raised. This is not golang')
|
||||
except Error:
|
||||
pass
|
||||
request.assert_called_with(
|
||||
url=endpoint + '/',
|
||||
method='GET',
|
||||
params={'input': 'hello',
|
||||
'algorithm': 'NONEXISTENT'})
|
||||
|
||||
def test_plugins(self):
|
||||
endpoint = 'http://dummy/'
|
||||
@ -37,11 +30,8 @@ class ModelsTest(TestCase):
|
||||
plugins = Plugins()
|
||||
p1 = AnalysisPlugin({'name': 'AnalysisP1', 'version': 0, 'description': 'No'})
|
||||
plugins.plugins = [p1, ]
|
||||
with patch_requests(plugins) as (request, response):
|
||||
with patch_requests('http://dummy/plugins', plugins):
|
||||
response = client.plugins()
|
||||
assert isinstance(response, dict)
|
||||
assert len(response) == 1
|
||||
assert "AnalysisP1" in response
|
||||
request.assert_called_with(
|
||||
url=endpoint + '/plugins', method='GET',
|
||||
params={})
|
||||
|
@ -5,28 +5,29 @@ import json
|
||||
from senpy.testing import patch_requests
|
||||
from senpy.models import Results
|
||||
|
||||
ENDPOINT = 'http://example.com'
|
||||
|
||||
|
||||
class TestTest(TestCase):
|
||||
def test_patch_text(self):
|
||||
with patch_requests('hello'):
|
||||
r = requests.get('http://example.com')
|
||||
with patch_requests(ENDPOINT, 'hello'):
|
||||
r = requests.get(ENDPOINT)
|
||||
assert r.text == 'hello'
|
||||
assert r.content == 'hello'
|
||||
|
||||
def test_patch_json(self):
|
||||
r = Results()
|
||||
with patch_requests(r):
|
||||
res = requests.get('http://example.com')
|
||||
assert res.content == json.dumps(r.jsonld())
|
||||
with patch_requests(ENDPOINT, r):
|
||||
res = requests.get(ENDPOINT)
|
||||
assert res.text == json.dumps(r.jsonld())
|
||||
js = res.json()
|
||||
assert js
|
||||
assert js['@type'] == r['@type']
|
||||
|
||||
def test_patch_dict(self):
|
||||
r = {'nothing': 'new'}
|
||||
with patch_requests(r):
|
||||
res = requests.get('http://example.com')
|
||||
assert res.content == json.dumps(r)
|
||||
with patch_requests(ENDPOINT, r):
|
||||
res = requests.get(ENDPOINT)
|
||||
assert res.text == json.dumps(r)
|
||||
js = res.json()
|
||||
assert js
|
||||
assert js['nothing'] == 'new'
|
||||
|
Loading…
Reference in New Issue
Block a user