Skip to content

Commit 44fbdce

Browse files
authored
feat(dev): Add fixtures for testing traces_sampler (getsentry#867)
Adds `StringContaining` and `DictionaryContaining` matchers for assertions about function call arguments.
1 parent 1cf5d8d commit 44fbdce

File tree

3 files changed

+90
-0
lines changed

3 files changed

+90
-0
lines changed

test-requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ pytest-localserver==0.5.0
66
pytest-cov==2.8.1
77
jsonschema==3.2.0
88
pyrsistent==0.16.0 # TODO(py3): 0.17.0 requires python3, see https://github.com/tobgu/pyrsistent/issues/205
9+
mock # for testing under python < 3.3
910

1011
gevent
1112
eventlet

tests/conftest.py

+86
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
import json
3+
from types import FunctionType
34

45
import pytest
56
import jsonschema
@@ -36,6 +37,11 @@ def benchmark():
3637
else:
3738
del pytest_benchmark
3839

40+
try:
41+
from unittest import mock # python 3.3 and above
42+
except ImportError:
43+
import mock # python < 3.3
44+
3945

4046
@pytest.fixture(autouse=True)
4147
def internal_exceptions(request, monkeypatch):
@@ -327,3 +333,83 @@ def render_span(span):
327333
return "\n".join(render_span(root_span))
328334

329335
return inner
336+
337+
338+
@pytest.fixture(name="StringContaining")
339+
def string_containing_matcher():
340+
"""
341+
An object which matches any string containing the substring passed to the
342+
object at instantiation time.
343+
344+
Useful for assert_called_with, assert_any_call, etc.
345+
346+
Used like this:
347+
348+
>>> f = mock.Mock(return_value=None)
349+
>>> f("dogs are great")
350+
>>> f.assert_any_call("dogs") # will raise AssertionError
351+
Traceback (most recent call last):
352+
...
353+
AssertionError: mock('dogs') call not found
354+
>>> f.assert_any_call(StringContaining("dogs")) # no AssertionError
355+
356+
"""
357+
358+
class StringContaining(object):
359+
def __init__(self, substring):
360+
self.substring = substring
361+
362+
def __eq__(self, test_string):
363+
if not isinstance(test_string, str):
364+
return False
365+
366+
return self.substring in test_string
367+
368+
return StringContaining
369+
370+
371+
@pytest.fixture(name="DictionaryContaining")
372+
def dictionary_containing_matcher():
373+
"""
374+
An object which matches any dictionary containing all key-value pairs from
375+
the dictionary passed to the object at instantiation time.
376+
377+
Useful for assert_called_with, assert_any_call, etc.
378+
379+
Used like this:
380+
381+
>>> f = mock.Mock(return_value=None)
382+
>>> f({"dogs": "yes", "cats": "maybe"})
383+
>>> f.assert_any_call({"dogs": "yes"}) # will raise AssertionError
384+
Traceback (most recent call last):
385+
...
386+
AssertionError: mock({'dogs': 'yes'}) call not found
387+
>>> f.assert_any_call(DictionaryContaining({"dogs": "yes"})) # no AssertionError
388+
"""
389+
390+
class DictionaryContaining(object):
391+
def __init__(self, subdict):
392+
self.subdict = subdict
393+
394+
def __eq__(self, test_dict):
395+
if not isinstance(test_dict, dict):
396+
return False
397+
398+
return all(test_dict.get(key) == self.subdict[key] for key in self.subdict)
399+
400+
return DictionaryContaining
401+
402+
403+
@pytest.fixture(name="FunctionMock")
404+
def function_mock():
405+
"""
406+
Just like a mock.Mock object, but one which always passes an isfunction
407+
test.
408+
"""
409+
410+
class FunctionMock(mock.Mock):
411+
def __init__(self, *args, **kwargs):
412+
super(FunctionMock, self).__init__(*args, **kwargs)
413+
self.__class__ = FunctionType
414+
415+
return FunctionMock

tox.ini

+3
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ envlist =
8383

8484
[testenv]
8585
deps =
86+
# if you change test-requirements.txt and your change is not being reflected
87+
# in what's installed by tox (when running tox locally), try running tox
88+
# with the -r flag
8689
-r test-requirements.txt
8790

8891
django-{1.11,2.0,2.1,2.2,3.0,3.1,dev}: djangorestframework>=3.0.0,<4.0.0

0 commit comments

Comments
 (0)