Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add mockito dependency

  • Loading branch information...
commit b4c8b4229d8f95b499466af7bbd573e29bbf8a49 1 parent eec7380
Ryan Tomac authored
27 test/lib/mockito/__init__.py
View
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+# coding: utf-8
+
+'''Mockito is a Test Spy framework.'''
+
+__copyright__ = "Copyright 2008-2010, Mockito Contributors"
+__license__ = "MIT"
+__maintainer__ = "Mockito Maintainers"
+__email__ = "mockito-python@googlegroups.com"
+
+from mockito import mock, verify, verifyNoMoreInteractions, verifyZeroInteractions, when, unstub, ArgumentError
+import inorder
+from spying import spy
+from verification import VerificationError
+
+# Imports for compatibility
+from mocking import Mock
+from matchers import any, contains, times # use package import (``from mockito.matchers import any, contains``) instead of ``from mockito import any, contains``
+from verification import never
+
+__all__ = ['mock', 'spy', 'verify', 'verifyNoMoreInteractions', 'verifyZeroInteractions', 'inorder', 'when', 'unstub', 'VerificationError', 'ArgumentError',
+ 'Mock', # deprecated
+ 'any', # compatibility
+ 'contains', # compatibility
+ 'never', # compatibility
+ 'times' # deprecated
+ ]
15 test/lib/mockito/inorder.py
View
@@ -0,0 +1,15 @@
+#!/usr/bin/env python3
+# coding: utf-8
+
+from mockito import verify as verify_main
+
+__author__ = "Serhiy Oplakanets <serhiy@oplakanets.com>"
+__copyright__ = "Copyright 2008-2010, Mockito Contributors"
+__license__ = "MIT"
+__maintainer__ = "Mockito Maintainers"
+__email__ = "mockito-python@googlegroups.com"
+
+def verify(object, *args, **kwargs):
+ kwargs['inorder'] = True
+ return verify_main(object, *args, **kwargs)
+
175 test/lib/mockito/invocation.py
View
@@ -0,0 +1,175 @@
+#!/usr/bin/env python
+# coding: utf-8
+
+import matchers
+
+__copyright__ = "Copyright 2008-2010, Mockito Contributors"
+__license__ = "MIT"
+__maintainer__ = "Mockito Maintainers"
+__email__ = "mockito-python@googlegroups.com"
+
+class InvocationError(AssertionError):
+ pass
+
+class Invocation(object):
+ def __init__(self, mock, method_name):
+ self.method_name = method_name
+ self.mock = mock
+ self.verified = False
+ self.verified_inorder = False
+ self.params = ()
+ self.named_params = {}
+ self.answers = []
+ self.strict = mock.strict
+
+ def _remember_params(self, params, named_params):
+ self.params = params
+ self.named_params = named_params
+
+ def __repr__(self):
+ return self.method_name + "(" + ", ".join([repr(p) for p in self.params]) + ")"
+
+ def answer_first(self):
+ return self.answers[0].answer()
+
+class MatchingInvocation(Invocation):
+ @staticmethod
+ def compare(p1, p2):
+ if isinstance(p1, matchers.Matcher):
+ if not p1.matches(p2): return False
+ elif p1 != p2: return False
+ return True
+
+ def matches(self, invocation):
+ if self.method_name != invocation.method_name:
+ return False
+ if len(self.params) != len(invocation.params):
+ return False
+ if len(self.named_params) != len(invocation.named_params):
+ return False
+ if self.named_params.keys() != invocation.named_params.keys():
+ return False
+
+ for x, p1 in enumerate(self.params):
+ if not self.compare(p1, invocation.params[x]):
+ return False
+
+ for x, p1 in self.named_params.iteritems():
+ if not self.compare(p1, invocation.named_params[x]):
+ return False
+
+ return True
+
+class RememberedInvocation(Invocation):
+ def __call__(self, *params, **named_params):
+ self._remember_params(params, named_params)
+ self.mock.remember(self)
+
+ for matching_invocation in self.mock.stubbed_invocations:
+ if matching_invocation.matches(self):
+ return matching_invocation.answer_first()
+
+ return None
+
+class RememberedProxyInvocation(Invocation):
+ '''Remeber params and proxy to method of original object.
+
+ Calls method on original object and returns it's return value.
+ '''
+ def __call__(self, *params, **named_params):
+ self._remember_params(params, named_params)
+ self.mock.remember(self)
+ obj = self.mock.original_object
+ try:
+ method = getattr(obj, self.method_name)
+ except AttributeError:
+ raise AttributeError("You tried to call method '%s' which '%s' instance does not have." % (self.method_name, obj.__class__.__name__))
+ return method(*params, **named_params)
+
+class VerifiableInvocation(MatchingInvocation):
+ def __call__(self, *params, **named_params):
+ self._remember_params(params, named_params)
+ matched_invocations = []
+ for invocation in self.mock.invocations:
+ if self.matches(invocation):
+ matched_invocations.append(invocation)
+
+ verification = self.mock.pull_verification()
+ verification.verify(self, len(matched_invocations))
+
+ for invocation in matched_invocations:
+ invocation.verified = True
+
+class StubbedInvocation(MatchingInvocation):
+ def __init__(self, *params):
+ super(StubbedInvocation, self).__init__(*params)
+ if self.mock.strict:
+ self.ensure_mocked_object_has_method(self.method_name)
+
+ def ensure_mocked_object_has_method(self, method_name):
+ if not self.mock.has_method(method_name):
+ raise InvocationError("You tried to stub a method '%s' the object (%s) doesn't have."
+ % (method_name, self.mock.mocked_obj))
+
+
+ def __call__(self, *params, **named_params):
+ self._remember_params(params, named_params)
+ return AnswerSelector(self)
+
+ def stub_with(self, answer):
+ self.answers.append(answer)
+ self.mock.stub(self.method_name)
+ self.mock.finish_stubbing(self)
+
+class AnswerSelector(object):
+ def __init__(self, invocation):
+ self.invocation = invocation
+ self.answer = None
+
+ def thenReturn(self, *return_values):
+ for return_value in return_values:
+ self.__then(Return(return_value))
+ return self
+
+ def thenRaise(self, *exceptions):
+ for exception in exceptions:
+ self.__then(Raise(exception))
+ return self
+
+ def __then(self, answer):
+ if not self.answer:
+ self.answer = CompositeAnswer(answer)
+ self.invocation.stub_with(self.answer)
+ else:
+ self.answer.add(answer)
+
+ return self
+
+class CompositeAnswer(object):
+ def __init__(self, answer):
+ self.answers = [answer]
+
+ def add(self, answer):
+ self.answers.insert(0, answer)
+
+ def answer(self):
+ if len(self.answers) > 1:
+ a = self.answers.pop()
+ else:
+ a = self.answers[0]
+
+ return a.answer()
+
+class Raise(object):
+ def __init__(self, exception):
+ self.exception = exception
+
+ def answer(self):
+ raise self.exception
+
+class Return(object):
+ def __init__(self, return_value):
+ self.return_value = return_value
+
+ def answer(self):
+ return self.return_value
58 test/lib/mockito/matchers.py
View
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+# coding: utf-8
+
+'''Matchers for stubbing and verifications.
+
+Common matchers for use in stubbing and verifications.
+'''
+
+__copyright__ = "Copyright 2008-2010, Mockito Contributors"
+__license__ = "MIT"
+__maintainer__ = "Mockito Maintainers"
+__email__ = "mockito-python@googlegroups.com"
+
+__all__ = ['any', 'contains', 'times']
+
+class Matcher:
+ def matches(self, arg):
+ pass
+
+class Any(Matcher):
+ def __init__(self, wanted_type=None):
+ self.wanted_type = wanted_type
+
+ def matches(self, arg):
+ if self.wanted_type:
+ return isinstance(arg, self.wanted_type)
+ else:
+ return True
+
+ def __repr__(self):
+ return "<Any: %s>" % self.wanted_type
+
+class Contains(Matcher):
+ def __init__(self, sub):
+ self.sub = sub
+
+ def matches(self, arg):
+ if not hasattr(arg, 'find'):
+ return
+ return self.sub and len(self.sub) > 0 and arg.find(self.sub) > -1
+
+ def __repr__(self):
+ return "<Contains: '%s'>" % self.sub
+
+
+def any(wanted_type=None):
+ """Matches any() argument OR any(SomeClass) argument
+ Examples:
+ when(mock).foo(any()).thenReturn(1)
+ verify(mock).foo(any(int))
+ """
+ return Any(wanted_type)
+
+def contains(sub):
+ return Contains(sub)
+
+def times(count):
+ return count
19 test/lib/mockito/mock_registry.py
View
@@ -0,0 +1,19 @@
+class MockRegistry:
+ """Registers mock()s, ensures that we only have one mock() per mocked_obj, and
+ iterates over them to unstub each stubbed method. """
+
+ def __init__(self):
+ self.mocks = {}
+
+ def register(self, mock):
+ self.mocks[mock.mocked_obj] = mock
+
+ def mock_for(self, cls):
+ return self.mocks.get(cls, None)
+
+ def unstub_all(self):
+ for mock in self.mocks.itervalues():
+ mock.unstub()
+ self.mocks.clear()
+
+mock_registry = MockRegistry()
106 test/lib/mockito/mocking.py
View
@@ -0,0 +1,106 @@
+#!/usr/bin/env python
+# coding: utf-8
+
+import inspect
+import invocation
+from mock_registry import mock_registry
+import warnings
+
+__copyright__ = "Copyright 2008-2010, Mockito Contributors"
+__license__ = "MIT"
+__maintainer__ = "Mockito Maintainers"
+__email__ = "mockito-python@googlegroups.com"
+
+__all__ = ['mock', 'Mock']
+
+class _Dummy(object): pass
+
+class TestDouble(object): pass
+
+class mock(TestDouble):
+ def __init__(self, mocked_obj=None, strict=True):
+ self.invocations = []
+ self.stubbed_invocations = []
+ self.original_methods = []
+ self.stubbing = None
+ self.verification = None
+ if mocked_obj is None:
+ mocked_obj = _Dummy()
+ strict = False
+ self.mocked_obj = mocked_obj
+ self.strict = strict
+ self.stubbing_real_object = False
+
+ mock_registry.register(self)
+
+ def __getattr__(self, method_name):
+ if self.stubbing is not None:
+ return invocation.StubbedInvocation(self, method_name)
+
+ if self.verification is not None:
+ return invocation.VerifiableInvocation(self, method_name)
+
+ return invocation.RememberedInvocation(self, method_name)
+
+ def remember(self, invocation):
+ self.invocations.insert(0, invocation)
+
+ def finish_stubbing(self, stubbed_invocation):
+ self.stubbed_invocations.insert(0, stubbed_invocation)
+ self.stubbing = None
+
+ def expect_stubbing(self):
+ self.stubbing = True
+
+ def pull_verification(self):
+ v = self.verification
+ self.verification = None
+ return v
+
+ def has_method(self, method_name):
+ return hasattr(self.mocked_obj, method_name)
+
+ def get_method(self, method_name):
+ return self.mocked_obj.__dict__.get(method_name)
+
+ def set_method(self, method_name, new_method):
+ setattr(self.mocked_obj, method_name, new_method)
+
+ def replace_method(self, method_name, original_method):
+
+ def new_mocked_method(*args, **kwargs):
+ # we throw away the first argument, if it's either self or cls
+ if inspect.isclass(self.mocked_obj) and not isinstance(original_method, staticmethod):
+ args = args[1:]
+ call = self.__getattr__(method_name) # that is: invocation.RememberedInvocation(self, method_name)
+ return call(*args, **kwargs)
+
+ if isinstance(original_method, staticmethod):
+ new_mocked_method = staticmethod(new_mocked_method)
+ elif isinstance(original_method, classmethod):
+ new_mocked_method = classmethod(new_mocked_method)
+
+ self.set_method(method_name, new_mocked_method)
+
+ def stub(self, method_name):
+ original_method = self.get_method(method_name)
+ original = (method_name, original_method)
+ self.original_methods.append(original)
+
+ # If we're trying to stub real object(not a generated mock), then we should patch object to use our mock method.
+ # TODO: Polymorphism was invented long time ago. Refactor this.
+ if self.stubbing_real_object:
+ self.replace_method(method_name, original_method)
+
+ def unstub(self):
+ while self.original_methods:
+ method_name, original_method = self.original_methods.pop()
+ self.set_method(method_name, original_method)
+
+def Mock(*args, **kwargs):
+ '''A ``mock``() alias.
+
+ Alias for compatibility. To be removed in version 1.0.
+ '''
+ warnings.warn("\n`Mock()` is deprecated, please use `mock()` (lower 'm') instead.", DeprecationWarning)
+ return mock(*args, **kwargs)
93 test/lib/mockito/mockito.py
View
@@ -0,0 +1,93 @@
+#!/usr/bin/env python
+# coding: utf-8
+
+import verification
+from mocking import mock, TestDouble
+from mock_registry import mock_registry
+from verification import VerificationError
+
+__copyright__ = "Copyright 2008-2010, Mockito Contributors"
+__license__ = "MIT"
+__maintainer__ = "Mockito Maintainers"
+__email__ = "mockito-python@googlegroups.com"
+
+class ArgumentError(Exception):
+ pass
+
+def _multiple_arguments_in_use(*args):
+ return len(filter(lambda x: x, args)) > 1
+
+def _invalid_argument(value):
+ return (value is not None and value < 1) or value == 0
+
+def _invalid_between(between):
+ if between is not None:
+ start, end = between
+ if start > end or start < 0:
+ return True
+ return False
+
+def verify(obj, times=1, atleast=None, atmost=None, between=None, inorder=False):
+ if times < 0:
+ raise ArgumentError("""'times' argument has invalid value.
+ It should be at least 0. You wanted to set it to: %i""" % times)
+ if _multiple_arguments_in_use(atleast, atmost, between):
+ raise ArgumentError("""Sure you know what you are doing?
+ You can set only one of the arguments: 'atleast', 'atmost' or 'between'.""")
+ if _invalid_argument(atleast):
+ raise ArgumentError("""'atleast' argument has invalid value.
+ It should be at least 1. You wanted to set it to: %i""" % atleast)
+ if _invalid_argument(atmost):
+ raise ArgumentError("""'atmost' argument has invalid value.
+ It should be at least 1. You wanted to set it to: %i""" % atmost)
+ if _invalid_between(between):
+ raise ArgumentError("""'between' argument has invalid value.
+ It should consist of positive values with second number not greater than first
+ e.g. [1, 4] or [0, 3] or [2, 2]
+ You wanted to set it to: %s""" % between)
+
+ if isinstance(obj, TestDouble):
+ mocked_object = obj
+ else:
+ mocked_object = mock_registry.mock_for(obj)
+
+ if atleast:
+ mocked_object.verification = verification.AtLeast(atleast)
+ elif atmost:
+ mocked_object.verification = verification.AtMost(atmost)
+ elif between:
+ mocked_object.verification = verification.Between(*between)
+ else:
+ mocked_object.verification = verification.Times(times)
+
+ if inorder:
+ mocked_object.verification = verification.InOrder(mocked_object.verification)
+
+ return mocked_object
+
+def when(obj, strict=True):
+ if isinstance(obj, mock):
+ theMock = obj
+ else:
+ theMock = mock_registry.mock_for(obj)
+ if theMock is None:
+ theMock = mock(obj, strict=strict)
+ # If we call when on something that is not TestDouble that means we're trying to stub real object,
+ # (class, module etc.). Not to be confused with generating stubs from real classes.
+ theMock.stubbing_real_object = True
+
+ theMock.expect_stubbing()
+ return theMock
+
+def unstub():
+ """Unstubs all stubbed methods and functions"""
+ mock_registry.unstub_all()
+
+def verifyNoMoreInteractions(*mocks):
+ for mock in mocks:
+ for i in mock.invocations:
+ if not i.verified:
+ raise VerificationError("\nUnwanted interaction: " + str(i))
+
+def verifyZeroInteractions(*mocks):
+ verifyNoMoreInteractions(*mocks)
41 test/lib/mockito/spying.py
View
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+# coding: utf-8
+
+'''Spying on real objects.'''
+
+from invocation import RememberedProxyInvocation, VerifiableInvocation
+from mocking import TestDouble
+
+__author__ = "Serhiy Oplakanets <serhiy@oplakanets.com>"
+__copyright__ = "Copyright 2009-2010, Mockito Contributors"
+__license__ = "MIT"
+__maintainer__ = "Mockito Maintainers"
+__email__ = "mockito-python@googlegroups.com"
+
+__all__ = ['spy']
+
+def spy(original_object):
+ return Spy(original_object)
+
+class Spy(TestDouble):
+ strict = True # spies always have to check if method exists
+
+ def __init__(self, original_object):
+ self.original_object = original_object
+ self.invocations = []
+ self.verification = None
+
+ def __getattr__(self, name):
+ if self.verification:
+ return VerifiableInvocation(self, name)
+ else:
+ return RememberedProxyInvocation(self, name)
+
+ def remember(self, invocation):
+ self.invocations.insert(0, invocation)
+
+ def pull_verification(self):
+ v = self.verification
+ self.verification = None
+ return v
+
81 test/lib/mockito/verification.py
View
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+# coding: utf-8
+
+__copyright__ = "Copyright 2008-2010, Mockito Contributors"
+__license__ = "MIT"
+__maintainer__ = "Mockito Maintainers"
+__email__ = "mockito-python@googlegroups.com"
+
+__all__ = ['never', 'VerificationError']
+
+class VerificationError(AssertionError):
+ '''Indicates error during verification of invocations.
+
+ Raised if verification fails. Error message contains the cause.
+ '''
+ pass
+
+class AtLeast(object):
+ def __init__(self, wanted_count):
+ self.wanted_count = wanted_count
+
+ def verify(self, invocation, actual_count):
+ if actual_count < self.wanted_count:
+ raise VerificationError("\nWanted at least: %i, actual times: %i" % (self.wanted_count, actual_count))
+
+class AtMost(object):
+ def __init__(self, wanted_count):
+ self.wanted_count = wanted_count
+
+ def verify(self, invocation, actual_count):
+ if actual_count > self.wanted_count:
+ raise VerificationError("\nWanted at most: %i, actual times: %i" % (self.wanted_count, actual_count))
+
+class Between(object):
+ def __init__(self, wanted_from, wanted_to):
+ self.wanted_from = wanted_from
+ self.wanted_to = wanted_to
+
+ def verify(self, invocation, actual_count):
+ if actual_count < self.wanted_from or actual_count > self.wanted_to:
+ raise VerificationError("\nWanted between: [%i, %i], actual times: %i" % (self.wanted_from, self.wanted_to, actual_count))
+
+class Times(object):
+ def __init__(self, wanted_count):
+ self.wanted_count = wanted_count
+
+ def verify(self, invocation, actual_count):
+ if actual_count == self.wanted_count:
+ return
+ if actual_count == 0:
+ raise VerificationError("\nWanted but not invoked: %s" % (invocation))
+ else:
+ if self.wanted_count == 0:
+ raise VerificationError("\nUnwanted invocation of %s, times: %i" % (invocation, actual_count))
+ else:
+ raise VerificationError("\nWanted times: %i, actual times: %i" % (self.wanted_count, actual_count))
+
+class InOrder(object):
+ '''
+ Verifies invocations in order.
+
+ Verifies if invocation was in expected order, and if yes -- degrades to original Verifier (AtLeast, Times, Between, ...).
+ '''
+
+ def __init__(self, original_verification):
+ '''
+ @param original_verification: Original verifiaction to degrade to if order of invocation was ok.
+ '''
+ self.original_verification = original_verification
+
+ def verify(self, wanted_invocation, count):
+ for invocation in reversed(wanted_invocation.mock.invocations):
+ if not invocation.verified_inorder:
+ if not wanted_invocation.matches(invocation):
+ raise VerificationError("\nWanted %s to be invoked, got %s instead" % (wanted_invocation, invocation))
+ invocation.verified_inorder = True
+ break
+ # proceed with original verification
+ self.original_verification.verify(wanted_invocation, count)
+
+never = 0
7 test/run_unit_tests.py
View
@@ -8,8 +8,13 @@ def run_unit_tests():
testfile = re.compile("^test_.*\.py$", re.IGNORECASE)
basedir = os.path.abspath(os.path.dirname(__file__))
testdir = os.path.join(basedir, 'unit')
+ path_dirs = [
+ testdir,
+ os.path.join(basedir, 'lib'),
+ os.path.join(basedir, '..', 'src')
+ ]
- for path in [testdir, os.path.join(basedir, '..', 'src')]:
+ for path in path_dirs:
if path not in sys.path:
sys.path.insert(0, path)
37 test/unit/test_browsercache.py
View
@@ -1,8 +1,9 @@
import unittest
import os
from Selenium2Library.browsercache import BrowserCache
+from mockito import *
-class MyTests(unittest.TestCase):
+class BrowserCacheTests(unittest.TestCase):
def test_no_current_message(self):
cache = BrowserCache()
@@ -10,33 +11,33 @@ def test_no_current_message(self):
cache.current.anyMember()
self.assertEqual(context.exception.message, "No current browser")
+ def test_close(self):
+ cache = BrowserCache()
+ browser = mock()
+ cache.register(browser)
+
+ verify(browser, times=0).close() # sanity check
+ cache.close()
+ verify(browser, times=1).close()
+
def test_close_only_called_once(self):
cache = BrowserCache()
- browser1 = FakeBrowser()
- browser2 = FakeBrowser()
- browser3 = FakeBrowser()
+ browser1 = mock()
+ browser2 = mock()
+ browser3 = mock()
cache.register(browser1)
cache.register(browser2)
cache.register(browser3)
- self.assertIs(cache.current, browser3) # sanity check
- cache.close() # called on browser3
- self.assertEquals(browser3.close_count, 1) # ensure close called
+ cache.close()
+ verify(browser3, times=1).close()
cache.close_all()
- self.assertEquals(browser1.close_count, 1)
- self.assertEquals(browser2.close_count, 1)
- self.assertEquals(browser3.close_count, 1)
-
-class FakeBrowser:
-
- def __init__(self):
- self.close_count = 0
-
- def close(self):
- self.close_count = self.close_count + 1
+ verify(browser1, times=1).close()
+ verify(browser2, times=1).close()
+ verify(browser3, times=1).close()
if __name__ == "__main__":
unittest.main()
Please sign in to comment.
Something went wrong with that request. Please try again.