From 1a99638ba2405211c6539c71060e89f8e98b53bb Mon Sep 17 00:00:00 2001 From: Monty Taylor Date: Tue, 21 May 2013 17:12:00 -0400 Subject: [PATCH] Fix the leading indentation issue. --- mox3/mox.py | 3200 ++++++++++++++--------------- mox3/stubout.py | 220 +- mox3/tests/mox_helper.py | 134 +- mox3/tests/stubout_helper.py | 2 +- mox3/tests/test_mox.py | 3760 +++++++++++++++++----------------- mox3/tests/test_stubout.py | 28 +- setup.py | 4 +- tox.ini | 2 +- 8 files changed, 3676 insertions(+), 3674 deletions(-) diff --git a/mox3/mox.py b/mox3/mox.py index da1d89b..ad3daf9 100644 --- a/mox3/mox.py +++ b/mox3/mox.py @@ -42,25 +42,25 @@ TODO(stevepm): Add the option to make mocks thread-safe! Suggested usage / workflow: - # Create Mox factory - my_mox = Mox() + # Create Mox factory + my_mox = Mox() - # Create a mock data access object - mock_dao = my_mox.CreateMock(DAOClass) + # Create a mock data access object + mock_dao = my_mox.CreateMock(DAOClass) - # Set up expected behavior - mock_dao.RetrievePersonWithIdentifier('1').AndReturn(person) - mock_dao.DeletePerson(person) + # Set up expected behavior + mock_dao.RetrievePersonWithIdentifier('1').AndReturn(person) + mock_dao.DeletePerson(person) - # Put mocks in replay mode - my_mox.ReplayAll() + # Put mocks in replay mode + my_mox.ReplayAll() - # Inject mock object and run test - controller.SetDao(mock_dao) - controller.DeletePersonById('1') + # Inject mock object and run test + controller.SetDao(mock_dao) + controller.DeletePersonById('1') - # Verify all methods were called as expected - my_mox.VerifyAll() + # Verify all methods were called as expected + my_mox.VerifyAll() """ from collections import deque @@ -74,2062 +74,2064 @@ from . import stubout class Error(AssertionError): - """Base exception for this module.""" + """Base exception for this module.""" - pass + pass class ExpectedMethodCallsError(Error): - """Raised when an expected method wasn't called. + """Raised when an expected method wasn't called. - This can occur if Verify() is called before all expected methods have been - called. - """ - - def __init__(self, expected_methods): - """Init exception. - - Args: - # expected_methods: A sequence of MockMethod objects that should have - # been called. - expected_methods: [MockMethod] - - Raises: - ValueError: if expected_methods contains no methods. + This can occur if Verify() is called before all expected methods have been + called. """ - if not expected_methods: - raise ValueError("There must be at least one expected method") - Error.__init__(self) - self._expected_methods = expected_methods + def __init__(self, expected_methods): + """Init exception. - def __str__(self): - calls = "\n".join(["%3d. %s" % (i, m) - for i, m in enumerate(self._expected_methods)]) - return "Verify: Expected methods never called:\n%s" % (calls,) + Args: + # expected_methods: A sequence of MockMethod objects that should + # have been called. + expected_methods: [MockMethod] + + Raises: + ValueError: if expected_methods contains no methods. + """ + + if not expected_methods: + raise ValueError("There must be at least one expected method") + Error.__init__(self) + self._expected_methods = expected_methods + + def __str__(self): + calls = "\n".join(["%3d. %s" % (i, m) + for i, m in enumerate(self._expected_methods)]) + return "Verify: Expected methods never called:\n%s" % (calls,) class UnexpectedMethodCallError(Error): - """Raised when an unexpected method is called. + """Raised when an unexpected method is called. - This can occur if a method is called with incorrect parameters, or out of the - specified order. - """ - - def __init__(self, unexpected_method, expected): - """Init exception. - - Args: - # unexpected_method: MockMethod that was called but was not at the head - # of the expected_method queue. - # expected: MockMethod or UnorderedGroup the method should have - # been in. - unexpected_method: MockMethod - expected: MockMethod or UnorderedGroup + This can occur if a method is called with incorrect parameters, or out of + the specified order. """ - Error.__init__(self) - if expected is None: - self._str = "Unexpected method call %s" % (unexpected_method,) - else: - differ = difflib.Differ() - diff = differ.compare(str(unexpected_method).splitlines(True), - str(expected).splitlines(True)) - self._str = ("Unexpected method call. unexpected:- expected:+\n%s" - % ("\n".join(line.rstrip() for line in diff),)) + def __init__(self, unexpected_method, expected): + """Init exception. - def __str__(self): - return self._str + Args: + # unexpected_method: MockMethod that was called but was not at the + # head of the expected_method queue. + # expected: MockMethod or UnorderedGroup the method should have + # been in. + unexpected_method: MockMethod + expected: MockMethod or UnorderedGroup + """ + + Error.__init__(self) + if expected is None: + self._str = "Unexpected method call %s" % (unexpected_method,) + else: + differ = difflib.Differ() + diff = differ.compare(str(unexpected_method).splitlines(True), + str(expected).splitlines(True)) + self._str = ("Unexpected method call." + " unexpected:- expected:+\n%s" + % ("\n".join(line.rstrip() for line in diff),)) + + def __str__(self): + return self._str class UnknownMethodCallError(Error): - """Raised if an unknown method is requested of the mock object.""" + """Raised if an unknown method is requested of the mock object.""" - def __init__(self, unknown_method_name): - """Init exception. + def __init__(self, unknown_method_name): + """Init exception. - Args: - # unknown_method_name: Method call that is not part of the mocked class's - # public interface. - unknown_method_name: str - """ + Args: + # unknown_method_name: Method call that is not part of the mocked + # class's public interface. + unknown_method_name: str + """ - Error.__init__(self) - self._unknown_method_name = unknown_method_name + Error.__init__(self) + self._unknown_method_name = unknown_method_name - def __str__(self): - return "Method called is not a member of the object: %s" % \ - self._unknown_method_name + def __str__(self): + return ("Method called is not a member of the object: %s" % + self._unknown_method_name) class PrivateAttributeError(Error): - """ - Raised if a MockObject is passed a private additional attribute name. - """ + """ + Raised if a MockObject is passed a private additional attribute name. + """ - def __init__(self, attr): - Error.__init__(self) - self._attr = attr + def __init__(self, attr): + Error.__init__(self) + self._attr = attr - def __str__(self): - return ("Attribute '%s' is private and should not be available in a mock " - "object." % self._attr) + def __str__(self): + return ("Attribute '%s' is private and should not be available" + "in a mock object." % self._attr) class ExpectedMockCreationError(Error): - """Raised if mocks should have been created by StubOutClassWithMocks.""" + """Raised if mocks should have been created by StubOutClassWithMocks.""" - def __init__(self, expected_mocks): - """Init exception. + def __init__(self, expected_mocks): + """Init exception. - Args: - # expected_mocks: A sequence of MockObjects that should have been - # created + Args: + # expected_mocks: A sequence of MockObjects that should have been + # created - Raises: - ValueError: if expected_mocks contains no methods. - """ + Raises: + ValueError: if expected_mocks contains no methods. + """ - if not expected_mocks: - raise ValueError("There must be at least one expected method") - Error.__init__(self) - self._expected_mocks = expected_mocks + if not expected_mocks: + raise ValueError("There must be at least one expected method") + Error.__init__(self) + self._expected_mocks = expected_mocks - def __str__(self): - mocks = "\n".join(["%3d. %s" % (i, m) - for i, m in enumerate(self._expected_mocks)]) - return "Verify: Expected mocks never created:\n%s" % (mocks,) + def __str__(self): + mocks = "\n".join(["%3d. %s" % (i, m) + for i, m in enumerate(self._expected_mocks)]) + return "Verify: Expected mocks never created:\n%s" % (mocks,) class UnexpectedMockCreationError(Error): - """Raised if too many mocks were created by StubOutClassWithMocks.""" + """Raised if too many mocks were created by StubOutClassWithMocks.""" - def __init__(self, instance, *params, **named_params): - """Init exception. + def __init__(self, instance, *params, **named_params): + """Init exception. - Args: - # instance: the type of obejct that was created - # params: parameters given during instantiation - # named_params: named parameters given during instantiation - """ + Args: + # instance: the type of obejct that was created + # params: parameters given during instantiation + # named_params: named parameters given during instantiation + """ - Error.__init__(self) - self._instance = instance - self._params = params - self._named_params = named_params + Error.__init__(self) + self._instance = instance + self._params = params + self._named_params = named_params - def __str__(self): - args = ", ".join(["%s" % v for i, v in enumerate(self._params)]) - error = "Unexpected mock creation: %s(%s" % (self._instance, args) + def __str__(self): + args = ", ".join(["%s" % v for i, v in enumerate(self._params)]) + error = "Unexpected mock creation: %s(%s" % (self._instance, args) - if self._named_params: - error += ", " + ", ".join(["%s=%s" % (k, v) for k, v in - self._named_params.items()]) + if self._named_params: + error += ", " + ", ".join(["%s=%s" % (k, v) for k, v in + self._named_params.items()]) - error += ")" - return error + error += ")" + return error class Mox(object): - """Mox: a factory for creating mock objects.""" + """Mox: a factory for creating mock objects.""" - # A list of types that should be stubbed out with MockObjects (as - # opposed to MockAnythings). - _USE_MOCK_OBJECT = [types.FunctionType, types.ModuleType, types.MethodType] + # A list of types that should be stubbed out with MockObjects (as + # opposed to MockAnythings). + _USE_MOCK_OBJECT = [types.FunctionType, types.ModuleType, types.MethodType] - def __init__(self): - """Initialize a new Mox.""" + def __init__(self): + """Initialize a new Mox.""" - self._mock_objects = [] - self.stubs = stubout.StubOutForTesting() + self._mock_objects = [] + self.stubs = stubout.StubOutForTesting() - def CreateMock(self, class_to_mock, attrs=None, bounded_to=None): - """Create a new mock object. + def CreateMock(self, class_to_mock, attrs=None, bounded_to=None): + """Create a new mock object. - Args: - # class_to_mock: the class to be mocked - class_to_mock: class - attrs: dict of attribute names to values that will be set on the mock - object. Only public attributes may be set. - bounded_to: optionally, when class_to_mock is not a class, it points - to a real class object, to which attribute is bound + Args: + # class_to_mock: the class to be mocked + class_to_mock: class + attrs: dict of attribute names to values that will be + set on the mock object. Only public attributes may be set. + bounded_to: optionally, when class_to_mock is not a class, + it points to a real class object, to which + attribute is bound - Returns: - MockObject that can be used as the class_to_mock would be. - """ - if attrs is None: - attrs = {} - new_mock = MockObject(class_to_mock, attrs=attrs, class_to_bind=bounded_to) - self._mock_objects.append(new_mock) - return new_mock + Returns: + MockObject that can be used as the class_to_mock would be. + """ + if attrs is None: + attrs = {} + new_mock = MockObject(class_to_mock, attrs=attrs, class_to_bind=bounded_to) + self._mock_objects.append(new_mock) + return new_mock - def CreateMockAnything(self, description=None): - """Create a mock that will accept any method calls. + def CreateMockAnything(self, description=None): + """Create a mock that will accept any method calls. - This does not enforce an interface. + This does not enforce an interface. - Args: - description: str. Optionally, a descriptive name for the mock object - being created, for debugging output purposes. - """ - new_mock = MockAnything(description=description) - self._mock_objects.append(new_mock) - return new_mock + Args: + description: str. Optionally, a descriptive name for the mock object + being created, for debugging output purposes. + """ + new_mock = MockAnything(description=description) + self._mock_objects.append(new_mock) + return new_mock - def ReplayAll(self): - """Set all mock objects to replay mode.""" + def ReplayAll(self): + """Set all mock objects to replay mode.""" - for mock_obj in self._mock_objects: - mock_obj._Replay() + for mock_obj in self._mock_objects: + mock_obj._Replay() - def VerifyAll(self): - """Call verify on all mock objects created.""" + def VerifyAll(self): + """Call verify on all mock objects created.""" - for mock_obj in self._mock_objects: - mock_obj._Verify() + for mock_obj in self._mock_objects: + mock_obj._Verify() - def ResetAll(self): - """Call reset on all mock objects. This does not unset stubs.""" + def ResetAll(self): + """Call reset on all mock objects. This does not unset stubs.""" - for mock_obj in self._mock_objects: - mock_obj._Reset() + for mock_obj in self._mock_objects: + mock_obj._Reset() - def StubOutWithMock(self, obj, attr_name, use_mock_anything=False): - """Replace a method, attribute, etc. with a Mock. + def StubOutWithMock(self, obj, attr_name, use_mock_anything=False): + """Replace a method, attribute, etc. with a Mock. - This will replace a class or module with a MockObject, and everything else - (method, function, etc) with a MockAnything. This can be overridden to - always use a MockAnything by setting use_mock_anything to True. + This will replace a class or module with a MockObject, and everything else + (method, function, etc) with a MockAnything. This can be overridden to + always use a MockAnything by setting use_mock_anything to True. - Args: - obj: A Python object (class, module, instance, callable). - attr_name: str. The name of the attribute to replace with a mock. - use_mock_anything: bool. True if a MockAnything should be used regardless - of the type of attribute. - """ + Args: + obj: A Python object (class, module, instance, callable). + attr_name: str. The name of the attribute to replace with a mock. + use_mock_anything: bool. True if a MockAnything should be used regardless + of the type of attribute. + """ - if inspect.isclass(obj): - class_to_bind = obj - else: - class_to_bind = None + if inspect.isclass(obj): + class_to_bind = obj + else: + class_to_bind = None - attr_to_replace = getattr(obj, attr_name) - attr_type = type(attr_to_replace) + attr_to_replace = getattr(obj, attr_name) + attr_type = type(attr_to_replace) - if attr_type == MockAnything or attr_type == MockObject: - raise TypeError('Cannot mock a MockAnything! Did you remember to ' - 'call UnsetStubs in your previous test?') + if attr_type == MockAnything or attr_type == MockObject: + raise TypeError('Cannot mock a MockAnything! Did you remember to ' + 'call UnsetStubs in your previous test?') - type_check = ( - attr_type in self._USE_MOCK_OBJECT or inspect.isclass(attr_to_replace) - or isinstance(attr_to_replace, object)) - if type_check and not use_mock_anything: - stub = self.CreateMock(attr_to_replace, bounded_to=class_to_bind) - else: - stub = self.CreateMockAnything( - description='Stub for %s' % attr_to_replace) - stub.__name__ = attr_name + type_check = ( + attr_type in self._USE_MOCK_OBJECT or inspect.isclass(attr_to_replace) + or isinstance(attr_to_replace, object)) + if type_check and not use_mock_anything: + stub = self.CreateMock(attr_to_replace, bounded_to=class_to_bind) + else: + stub = self.CreateMockAnything( + description='Stub for %s' % attr_to_replace) + stub.__name__ = attr_name - self.stubs.Set(obj, attr_name, stub) + self.stubs.Set(obj, attr_name, stub) - def StubOutClassWithMocks(self, obj, attr_name): - """Replace a class with a "mock factory" that will create mock objects. + def StubOutClassWithMocks(self, obj, attr_name): + """Replace a class with a "mock factory" that will create mock objects. - This is useful if the code-under-test directly instantiates - dependencies. Previously some boilder plate was necessary to - create a mock that would act as a factory. Using - StubOutClassWithMocks, once you've stubbed out the class you may - use the stubbed class as you would any other mock created by mox: - during the record phase, new mock instances will be created, and - during replay, the recorded mocks will be returned. + This is useful if the code-under-test directly instantiates + dependencies. Previously some boilder plate was necessary to + create a mock that would act as a factory. Using + StubOutClassWithMocks, once you've stubbed out the class you may + use the stubbed class as you would any other mock created by mox: + during the record phase, new mock instances will be created, and + during replay, the recorded mocks will be returned. - In replay mode + In replay mode - # Example using StubOutWithMock (the old, clunky way): + # Example using StubOutWithMock (the old, clunky way): - mock1 = mox.CreateMock(my_import.FooClass) - mock2 = mox.CreateMock(my_import.FooClass) - foo_factory = mox.StubOutWithMock(my_import, 'FooClass', - use_mock_anything=True) - foo_factory(1, 2).AndReturn(mock1) - foo_factory(9, 10).AndReturn(mock2) - mox.ReplayAll() + mock1 = mox.CreateMock(my_import.FooClass) + mock2 = mox.CreateMock(my_import.FooClass) + foo_factory = mox.StubOutWithMock(my_import, 'FooClass', + use_mock_anything=True) + foo_factory(1, 2).AndReturn(mock1) + foo_factory(9, 10).AndReturn(mock2) + mox.ReplayAll() - my_import.FooClass(1, 2) # Returns mock1 again. - my_import.FooClass(9, 10) # Returns mock2 again. - mox.VerifyAll() + my_import.FooClass(1, 2) # Returns mock1 again. + my_import.FooClass(9, 10) # Returns mock2 again. + mox.VerifyAll() - # Example using StubOutClassWithMocks: + # Example using StubOutClassWithMocks: - mox.StubOutClassWithMocks(my_import, 'FooClass') - mock1 = my_import.FooClass(1, 2) # Returns a new mock of FooClass - mock2 = my_import.FooClass(9, 10) # Returns another mock instance - mox.ReplayAll() + mox.StubOutClassWithMocks(my_import, 'FooClass') + mock1 = my_import.FooClass(1, 2) # Returns a new mock of FooClass + mock2 = my_import.FooClass(9, 10) # Returns another mock instance + mox.ReplayAll() - my_import.FooClass(1, 2) # Returns mock1 again. - my_import.FooClass(9, 10) # Returns mock2 again. - mox.VerifyAll() - """ - attr_to_replace = getattr(obj, attr_name) - attr_type = type(attr_to_replace) + my_import.FooClass(1, 2) # Returns mock1 again. + my_import.FooClass(9, 10) # Returns mock2 again. + mox.VerifyAll() + """ + attr_to_replace = getattr(obj, attr_name) + attr_type = type(attr_to_replace) - if attr_type == MockAnything or attr_type == MockObject: - raise TypeError('Cannot mock a MockAnything! Did you remember to ' - 'call UnsetStubs in your previous test?') + if attr_type == MockAnything or attr_type == MockObject: + raise TypeError('Cannot mock a MockAnything! Did you remember to ' + 'call UnsetStubs in your previous test?') - if not inspect.isclass(attr_to_replace): - raise TypeError('Given attr is not a Class. Use StubOutWithMock.') + if not inspect.isclass(attr_to_replace): + raise TypeError('Given attr is not a Class. Use StubOutWithMock.') - factory = _MockObjectFactory(attr_to_replace, self) - self._mock_objects.append(factory) - self.stubs.Set(obj, attr_name, factory) + factory = _MockObjectFactory(attr_to_replace, self) + self._mock_objects.append(factory) + self.stubs.Set(obj, attr_name, factory) - def UnsetStubs(self): - """Restore stubs to their original state.""" + def UnsetStubs(self): + """Restore stubs to their original state.""" - self.stubs.UnsetAll() + self.stubs.UnsetAll() def Replay(*args): - """Put mocks into Replay mode. + """Put mocks into Replay mode. - Args: - # args is any number of mocks to put into replay mode. - """ + Args: + # args is any number of mocks to put into replay mode. + """ - for mock in args: - mock._Replay() + for mock in args: + mock._Replay() def Verify(*args): - """Verify mocks. + """Verify mocks. - Args: - # args is any number of mocks to be verified. - """ + Args: + # args is any number of mocks to be verified. + """ - for mock in args: - mock._Verify() + for mock in args: + mock._Verify() def Reset(*args): - """Reset mocks. + """Reset mocks. - Args: - # args is any number of mocks to be reset. - """ + Args: + # args is any number of mocks to be reset. + """ - for mock in args: - mock._Reset() + for mock in args: + mock._Reset() class MockAnything(object): - """A mock that can be used to mock anything. + """A mock that can be used to mock anything. - This is helpful for mocking classes that do not provide a public interface. - """ - - def __init__(self, description=None): - """Initialize a new MockAnything. - - Args: - description: str. Optionally, a descriptive name for the mock object - being created, for debugging output purposes. - """ - self._description = description - self._Reset() - - def __repr__(self): - if self._description: - return '' % self._description - else: - return '' - - def __getattr__(self, method_name): - """Intercept method calls on this object. - - A new MockMethod is returned that is aware of the MockAnything's - state (record or replay). The call will be recorded or replayed - by the MockMethod's __call__. - - Args: - # method name: the name of the method being called. - method_name: str - - Returns: - A new MockMethod aware of MockAnything's state (record or replay). - """ - if method_name == '__dir__': - return self.__class__.__dir__.__get__(self, self.__class__) - - return self._CreateMockMethod(method_name) - - def __str__(self): - return self._CreateMockMethod('__str__')() - - def __call__(self, *args, **kwargs): - return self._CreateMockMethod('__call__')(*args, **kwargs) - - def __getitem__(self, i): - return self._CreateMockMethod('__getitem__')(i) - - def _CreateMockMethod(self, method_name, method_to_mock=None, - class_to_bind=object): - """Create a new mock method call and return it. - - Args: - # method_name: the name of the method being called. - # method_to_mock: The actual method being mocked, used for introspection. - # class_to_bind: Class to which method is bounded (object by default) - method_name: str - method_to_mock: a method object - - Returns: - A new MockMethod aware of MockAnything's state (record or replay). + This is helpful for mocking classes that do not provide a public interface. """ - return MockMethod(method_name, self._expected_calls_queue, - self._replay_mode, method_to_mock=method_to_mock, - description=self._description, - class_to_bind=class_to_bind) + def __init__(self, description=None): + """Initialize a new MockAnything. - def __nonzero__(self): - """Return 1 for nonzero so the mock can be used as a conditional.""" + Args: + description: str. Optionally, a descriptive name for the mock object + being created, for debugging output purposes. + """ + self._description = description + self._Reset() - return 1 + def __repr__(self): + if self._description: + return '' % self._description + else: + return '' - def __bool__(self): - """Return True for nonzero so the mock can be used as a conditional.""" - return True + def __getattr__(self, method_name): + """Intercept method calls on this object. - def __eq__(self, rhs): - """Provide custom logic to compare objects.""" + A new MockMethod is returned that is aware of the MockAnything's + state (record or replay). The call will be recorded or replayed + by the MockMethod's __call__. - return (isinstance(rhs, MockAnything) and - self._replay_mode == rhs._replay_mode and - self._expected_calls_queue == rhs._expected_calls_queue) + Args: + # method name: the name of the method being called. + method_name: str - def __ne__(self, rhs): - """Provide custom logic to compare objects.""" + Returns: + A new MockMethod aware of MockAnything's state (record or replay). + """ + if method_name == '__dir__': + return self.__class__.__dir__.__get__(self, self.__class__) - return not self == rhs + return self._CreateMockMethod(method_name) - def _Replay(self): - """Start replaying expected method calls.""" + def __str__(self): + return self._CreateMockMethod('__str__')() - self._replay_mode = True + def __call__(self, *args, **kwargs): + return self._CreateMockMethod('__call__')(*args, **kwargs) - def _Verify(self): - """Verify that all of the expected calls have been made. + def __getitem__(self, i): + return self._CreateMockMethod('__getitem__')(i) - Raises: - ExpectedMethodCallsError: if there are still more method calls in the - expected queue. - """ + def _CreateMockMethod(self, method_name, method_to_mock=None, + class_to_bind=object): + """Create a new mock method call and return it. - # If the list of expected calls is not empty, raise an exception - if self._expected_calls_queue: - # The last MultipleTimesGroup is not popped from the queue. - if (len(self._expected_calls_queue) == 1 and - isinstance(self._expected_calls_queue[0], MultipleTimesGroup) and - self._expected_calls_queue[0].IsSatisfied()): - pass - else: - raise ExpectedMethodCallsError(self._expected_calls_queue) + Args: + # method_name: the name of the method being called. + # method_to_mock: The actual method being mocked, used for introspection. + # class_to_bind: Class to which method is bounded (object by default) + method_name: str + method_to_mock: a method object - def _Reset(self): - """Reset the state of this mock to record mode with an empty queue.""" + Returns: + A new MockMethod aware of MockAnything's state (record or replay). + """ - # Maintain a list of method calls we are expecting - self._expected_calls_queue = deque() + return MockMethod(method_name, self._expected_calls_queue, + self._replay_mode, method_to_mock=method_to_mock, + description=self._description, + class_to_bind=class_to_bind) - # Make sure we are in setup mode, not replay mode - self._replay_mode = False + def __nonzero__(self): + """Return 1 for nonzero so the mock can be used as a conditional.""" + + return 1 + + def __bool__(self): + """Return True for nonzero so the mock can be used as a conditional.""" + return True + + def __eq__(self, rhs): + """Provide custom logic to compare objects.""" + + return (isinstance(rhs, MockAnything) and + self._replay_mode == rhs._replay_mode and + self._expected_calls_queue == rhs._expected_calls_queue) + + def __ne__(self, rhs): + """Provide custom logic to compare objects.""" + + return not self == rhs + + def _Replay(self): + """Start replaying expected method calls.""" + + self._replay_mode = True + + def _Verify(self): + """Verify that all of the expected calls have been made. + + Raises: + ExpectedMethodCallsError: if there are still more method calls in the + expected queue. + """ + + # If the list of expected calls is not empty, raise an exception + if self._expected_calls_queue: + # The last MultipleTimesGroup is not popped from the queue. + if (len(self._expected_calls_queue) == 1 and + isinstance(self._expected_calls_queue[0], MultipleTimesGroup) and + self._expected_calls_queue[0].IsSatisfied()): + pass + else: + raise ExpectedMethodCallsError(self._expected_calls_queue) + + def _Reset(self): + """Reset the state of this mock to record mode with an empty queue.""" + + # Maintain a list of method calls we are expecting + self._expected_calls_queue = deque() + + # Make sure we are in setup mode, not replay mode + self._replay_mode = False class MockObject(MockAnything): - """A mock object that simulates the public/protected interface of a class.""" + """A mock object that simulates the public/protected interface of a class.""" - def __init__(self, class_to_mock, attrs=None, class_to_bind=None): - """Initialize a mock object. + def __init__(self, class_to_mock, attrs=None, class_to_bind=None): + """Initialize a mock object. - This determines the methods and properties of the class and stores them. + This determines the methods and properties of the class and stores them. - Args: - # class_to_mock: class to be mocked - class_to_mock: class - attrs: dict of attribute names to values that will be set on the mock - object. Only public attributes may be set. - class_to_bind: optionally, when class_to_mock is not a class at all, it - points to a real class + Args: + # class_to_mock: class to be mocked + class_to_mock: class + attrs: dict of attribute names to values that will be set on the mock + object. Only public attributes may be set. + class_to_bind: optionally, when class_to_mock is not a class at all, it + points to a real class - Raises: - PrivateAttributeError: if a supplied attribute is not public. - ValueError: if an attribute would mask an existing method. - """ - if attrs is None: - attrs = {} + Raises: + PrivateAttributeError: if a supplied attribute is not public. + ValueError: if an attribute would mask an existing method. + """ + if attrs is None: + attrs = {} - # This is used to hack around the mixin/inheritance of MockAnything, which - # is not a proper object (it can be anything. :-) - MockAnything.__dict__['__init__'](self) + # This is used to hack around the mixin/inheritance of MockAnything, which + # is not a proper object (it can be anything. :-) + MockAnything.__dict__['__init__'](self) - # Get a list of all the public and special methods we should mock. - self._known_methods = set() - self._known_vars = set() - self._class_to_mock = class_to_mock + # Get a list of all the public and special methods we should mock. + self._known_methods = set() + self._known_vars = set() + self._class_to_mock = class_to_mock - if inspect.isclass(class_to_mock): - self._class_to_bind = self._class_to_mock - else: - self._class_to_bind = class_to_bind + if inspect.isclass(class_to_mock): + self._class_to_bind = self._class_to_mock + else: + self._class_to_bind = class_to_bind - try: - if inspect.isclass(self._class_to_mock): - self._description = class_to_mock.__name__ - else: - self._description = type(class_to_mock).__name__ - except Exception: - pass - - for method in dir(class_to_mock): - attr = getattr(class_to_mock, method) - if callable(attr): - self._known_methods.add(method) - elif not (type(attr) is property): - # treating properties as class vars makes little sense. - self._known_vars.add(method) - - # Set additional attributes at instantiation time; this is quicker - # than manually setting attributes that are normally created in - # __init__. - for attr, value in attrs.items(): - if attr.startswith("_"): - raise PrivateAttributeError(attr) - elif attr in self._known_methods: - raise ValueError("'%s' is a method of '%s' objects." % (attr, - class_to_mock)) - else: - setattr(self, attr, value) - - def _CreateMockMethod(self, *args, **kwargs): - """Overridden to provide self._class_to_mock to class_to_bind parameter.""" - kwargs.setdefault("class_to_bind", self._class_to_bind) - return super(MockObject, self)._CreateMockMethod(*args, **kwargs) - - def __getattr__(self, name): - """Intercept attribute request on this object. - - If the attribute is a public class variable, it will be returned and not - recorded as a call. - - If the attribute is not a variable, it is handled like a method - call. The method name is checked against the set of mockable - methods, and a new MockMethod is returned that is aware of the - MockObject's state (record or replay). The call will be recorded - or replayed by the MockMethod's __call__. - - Args: - # name: the name of the attribute being requested. - name: str - - Returns: - Either a class variable or a new MockMethod that is aware of the state - of the mock (record or replay). - - Raises: - UnknownMethodCallError if the MockObject does not mock the requested - method. - """ - - if name in self._known_vars: - return getattr(self._class_to_mock, name) - - if name in self._known_methods: - return self._CreateMockMethod( - name, - method_to_mock=getattr(self._class_to_mock, name)) - - raise UnknownMethodCallError(name) - - def __eq__(self, rhs): - """Provide custom logic to compare objects.""" - - return (isinstance(rhs, MockObject) and - self._class_to_mock == rhs._class_to_mock and - self._replay_mode == rhs._replay_mode and - self._expected_calls_queue == rhs._expected_calls_queue) - - def __setitem__(self, key, value): - """Provide custom logic for mocking classes that support item assignment. - - Args: - key: Key to set the value for. - value: Value to set. - - Returns: - Expected return value in replay mode. A MockMethod object for the - __setitem__ method that has already been called if not in replay mode. - - Raises: - TypeError if the underlying class does not support item assignment. - UnexpectedMethodCallError if the object does not expect the call to - __setitem__. - - """ - # Verify the class supports item assignment. - if '__setitem__' not in dir(self._class_to_mock): - raise TypeError('object does not support item assignment') - - # If we are in replay mode then simply call the mock __setitem__ method. - if self._replay_mode: - return MockMethod('__setitem__', self._expected_calls_queue, - self._replay_mode)(key, value) - - # Otherwise, create a mock method __setitem__. - return self._CreateMockMethod('__setitem__')(key, value) - - def __getitem__(self, key): - """Provide custom logic for mocking classes that are subscriptable. - - Args: - key: Key to return the value for. - - Returns: - Expected return value in replay mode. A MockMethod object for the - __getitem__ method that has already been called if not in replay mode. - - Raises: - TypeError if the underlying class is not subscriptable. - UnexpectedMethodCallError if the object does not expect the call to - __getitem__. - - """ - # Verify the class supports item assignment. - if '__getitem__' not in dir(self._class_to_mock): - raise TypeError('unsubscriptable object') - - # If we are in replay mode then simply call the mock __getitem__ method. - if self._replay_mode: - return MockMethod('__getitem__', self._expected_calls_queue, - self._replay_mode)(key) - - # Otherwise, create a mock method __getitem__. - return self._CreateMockMethod('__getitem__')(key) - - def __iter__(self): - """Provide custom logic for mocking classes that are iterable. - - Returns: - Expected return value in replay mode. A MockMethod object for the - __iter__ method that has already been called if not in replay mode. - - Raises: - TypeError if the underlying class is not iterable. - UnexpectedMethodCallError if the object does not expect the call to - __iter__. - - """ - methods = dir(self._class_to_mock) - - # Verify the class supports iteration. - if '__iter__' not in methods: - # If it doesn't have iter method and we are in replay method, then try to - # iterate using subscripts. - if '__getitem__' not in methods or not self._replay_mode: - raise TypeError('not iterable object') - else: - results = [] - index = 0 try: - while True: - results.append(self[index]) - index += 1 - except IndexError: - return iter(results) + if inspect.isclass(self._class_to_mock): + self._description = class_to_mock.__name__ + else: + self._description = type(class_to_mock).__name__ + except Exception: + pass - # If we are in replay mode then simply call the mock __iter__ method. - if self._replay_mode: - return MockMethod('__iter__', self._expected_calls_queue, - self._replay_mode)() + for method in dir(class_to_mock): + attr = getattr(class_to_mock, method) + if callable(attr): + self._known_methods.add(method) + elif not (type(attr) is property): + # treating properties as class vars makes little sense. + self._known_vars.add(method) - # Otherwise, create a mock method __iter__. - return self._CreateMockMethod('__iter__')() + # Set additional attributes at instantiation time; this is quicker + # than manually setting attributes that are normally created in + # __init__. + for attr, value in attrs.items(): + if attr.startswith("_"): + raise PrivateAttributeError(attr) + elif attr in self._known_methods: + raise ValueError("'%s' is a method of '%s' objects." % (attr, + class_to_mock)) + else: + setattr(self, attr, value) - def __contains__(self, key): - """Provide custom logic for mocking classes that contain items. + def _CreateMockMethod(self, *args, **kwargs): + """Overridden to provide self._class_to_mock to class_to_bind parameter.""" + kwargs.setdefault("class_to_bind", self._class_to_bind) + return super(MockObject, self)._CreateMockMethod(*args, **kwargs) - Args: - key: Key to look in container for. + def __getattr__(self, name): + """Intercept attribute request on this object. - Returns: - Expected return value in replay mode. A MockMethod object for the - __contains__ method that has already been called if not in replay mode. + If the attribute is a public class variable, it will be returned and not + recorded as a call. - Raises: - TypeError if the underlying class does not implement __contains__ - UnexpectedMethodCaller if the object does not expect the call to - __contains__. + If the attribute is not a variable, it is handled like a method + call. The method name is checked against the set of mockable + methods, and a new MockMethod is returned that is aware of the + MockObject's state (record or replay). The call will be recorded + or replayed by the MockMethod's __call__. - """ - contains = self._class_to_mock.__dict__.get('__contains__', None) + Args: + # name: the name of the attribute being requested. + name: str - if contains is None: - raise TypeError('unsubscriptable object') + Returns: + Either a class variable or a new MockMethod that is aware of the state + of the mock (record or replay). - if self._replay_mode: - return MockMethod('__contains__', self._expected_calls_queue, - self._replay_mode)(key) + Raises: + UnknownMethodCallError if the MockObject does not mock the requested + method. + """ - return self._CreateMockMethod('__contains__')(key) + if name in self._known_vars: + return getattr(self._class_to_mock, name) - def __call__(self, *params, **named_params): - """Provide custom logic for mocking classes that are callable.""" + if name in self._known_methods: + return self._CreateMockMethod( + name, + method_to_mock=getattr(self._class_to_mock, name)) - # Verify the class we are mocking is callable. - is_callable = hasattr(self._class_to_mock, '__call__') - if not is_callable: - raise TypeError('Not callable') + raise UnknownMethodCallError(name) - # Because the call is happening directly on this object instead of - # a method, the call on the mock method is made right here + def __eq__(self, rhs): + """Provide custom logic to compare objects.""" - # If we are mocking a Function, then use the function, and not the - # __call__ method - method = None - if type(self._class_to_mock) in (types.FunctionType, types.MethodType): - method = self._class_to_mock - else: - method = getattr(self._class_to_mock, '__call__') - mock_method = self._CreateMockMethod('__call__', method_to_mock=method) + return (isinstance(rhs, MockObject) and + self._class_to_mock == rhs._class_to_mock and + self._replay_mode == rhs._replay_mode and + self._expected_calls_queue == rhs._expected_calls_queue) - return mock_method(*params, **named_params) + def __setitem__(self, key, value): + """Provide custom logic for mocking classes that support item assignment. - @property - def __name__(self): - """Return the name that is being mocked.""" - return self._description + Args: + key: Key to set the value for. + value: Value to set. - # TODO(dejw): this property stopped to work after I introduced changes with - # binding classes. Fortunately I found a solution in the form of - # __getattribute__ method below, but this issue should be investigated - @property - def __class__(self): - return self._class_to_mock + Returns: + Expected return value in replay mode. A MockMethod object for the + __setitem__ method that has already been called if not in replay mode. - def __dir__(self): - """Return only attributes of a class to mock """ - return dir(self._class_to_mock) + Raises: + TypeError if the underlying class does not support item assignment. + UnexpectedMethodCallError if the object does not expect the call to + __setitem__. - def __getattribute__(self, name): - """Return _class_to_mock on __class__ attribute. """ - if name == "__class__": - return super(MockObject, self).__getattribute__("_class_to_mock") + """ + # Verify the class supports item assignment. + if '__setitem__' not in dir(self._class_to_mock): + raise TypeError('object does not support item assignment') - return super(MockObject, self).__getattribute__(name) + # If we are in replay mode then simply call the mock __setitem__ method. + if self._replay_mode: + return MockMethod('__setitem__', self._expected_calls_queue, + self._replay_mode)(key, value) + + # Otherwise, create a mock method __setitem__. + return self._CreateMockMethod('__setitem__')(key, value) + + def __getitem__(self, key): + """Provide custom logic for mocking classes that are subscriptable. + + Args: + key: Key to return the value for. + + Returns: + Expected return value in replay mode. A MockMethod object for the + __getitem__ method that has already been called if not in replay mode. + + Raises: + TypeError if the underlying class is not subscriptable. + UnexpectedMethodCallError if the object does not expect the call to + __getitem__. + + """ + # Verify the class supports item assignment. + if '__getitem__' not in dir(self._class_to_mock): + raise TypeError('unsubscriptable object') + + # If we are in replay mode then simply call the mock __getitem__ method. + if self._replay_mode: + return MockMethod('__getitem__', self._expected_calls_queue, + self._replay_mode)(key) + + # Otherwise, create a mock method __getitem__. + return self._CreateMockMethod('__getitem__')(key) + + def __iter__(self): + """Provide custom logic for mocking classes that are iterable. + + Returns: + Expected return value in replay mode. A MockMethod object for the + __iter__ method that has already been called if not in replay mode. + + Raises: + TypeError if the underlying class is not iterable. + UnexpectedMethodCallError if the object does not expect the call to + __iter__. + + """ + methods = dir(self._class_to_mock) + + # Verify the class supports iteration. + if '__iter__' not in methods: + # If it doesn't have iter method and we are in replay method, then try to + # iterate using subscripts. + if '__getitem__' not in methods or not self._replay_mode: + raise TypeError('not iterable object') + else: + results = [] + index = 0 + try: + while True: + results.append(self[index]) + index += 1 + except IndexError: + return iter(results) + + # If we are in replay mode then simply call the mock __iter__ method. + if self._replay_mode: + return MockMethod('__iter__', self._expected_calls_queue, + self._replay_mode)() + + # Otherwise, create a mock method __iter__. + return self._CreateMockMethod('__iter__')() + + def __contains__(self, key): + """Provide custom logic for mocking classes that contain items. + + Args: + key: Key to look in container for. + + Returns: + Expected return value in replay mode. A MockMethod object for the + __contains__ method that has already been called if not in replay mode. + + Raises: + TypeError if the underlying class does not implement __contains__ + UnexpectedMethodCaller if the object does not expect the call to + __contains__. + + """ + contains = self._class_to_mock.__dict__.get('__contains__', None) + + if contains is None: + raise TypeError('unsubscriptable object') + + if self._replay_mode: + return MockMethod('__contains__', self._expected_calls_queue, + self._replay_mode)(key) + + return self._CreateMockMethod('__contains__')(key) + + def __call__(self, *params, **named_params): + """Provide custom logic for mocking classes that are callable.""" + + # Verify the class we are mocking is callable. + is_callable = hasattr(self._class_to_mock, '__call__') + if not is_callable: + raise TypeError('Not callable') + + # Because the call is happening directly on this object instead of + # a method, the call on the mock method is made right here + + # If we are mocking a Function, then use the function, and not the + # __call__ method + method = None + if type(self._class_to_mock) in (types.FunctionType, types.MethodType): + method = self._class_to_mock + else: + method = getattr(self._class_to_mock, '__call__') + mock_method = self._CreateMockMethod('__call__', method_to_mock=method) + + return mock_method(*params, **named_params) + + @property + def __name__(self): + """Return the name that is being mocked.""" + return self._description + + # TODO(dejw): this property stopped to work after I introduced changes with + # binding classes. Fortunately I found a solution in the form of + # __getattribute__ method below, but this issue should be investigated + @property + def __class__(self): + return self._class_to_mock + + def __dir__(self): + """Return only attributes of a class to mock """ + return dir(self._class_to_mock) + + def __getattribute__(self, name): + """Return _class_to_mock on __class__ attribute. """ + if name == "__class__": + return super(MockObject, self).__getattribute__("_class_to_mock") + + return super(MockObject, self).__getattribute__(name) class _MockObjectFactory(MockObject): - """A MockObjectFactory creates mocks and verifies __init__ params. + """A MockObjectFactory creates mocks and verifies __init__ params. - A MockObjectFactory removes the boiler plate code that was previously - necessary to stub out direction instantiation of a class. + A MockObjectFactory removes the boiler plate code that was previously + necessary to stub out direction instantiation of a class. - The MockObjectFactory creates new MockObjects when called and verifies the - __init__ params are correct when in record mode. When replaying, existing - mocks are returned, and the __init__ params are verified. + The MockObjectFactory creates new MockObjects when called and verifies the + __init__ params are correct when in record mode. When replaying, existing + mocks are returned, and the __init__ params are verified. - See StubOutWithMock vs StubOutClassWithMocks for more detail. - """ + See StubOutWithMock vs StubOutClassWithMocks for more detail. + """ - def __init__(self, class_to_mock, mox_instance): - MockObject.__init__(self, class_to_mock) - self._mox = mox_instance - self._instance_queue = deque() + def __init__(self, class_to_mock, mox_instance): + MockObject.__init__(self, class_to_mock) + self._mox = mox_instance + self._instance_queue = deque() - def __call__(self, *params, **named_params): - """Instantiate and record that a new mock has been created.""" + def __call__(self, *params, **named_params): + """Instantiate and record that a new mock has been created.""" - method = getattr(self._class_to_mock, '__init__') - mock_method = self._CreateMockMethod('__init__', method_to_mock=method) - # Note: calling mock_method() is deferred in order to catch the - # empty instance_queue first. + method = getattr(self._class_to_mock, '__init__') + mock_method = self._CreateMockMethod('__init__', method_to_mock=method) + # Note: calling mock_method() is deferred in order to catch the + # empty instance_queue first. - if self._replay_mode: - if not self._instance_queue: - raise UnexpectedMockCreationError(self._class_to_mock, *params, - **named_params) + if self._replay_mode: + if not self._instance_queue: + raise UnexpectedMockCreationError(self._class_to_mock, *params, + **named_params) - mock_method(*params, **named_params) + mock_method(*params, **named_params) - return self._instance_queue.pop() - else: - mock_method(*params, **named_params) + return self._instance_queue.pop() + else: + mock_method(*params, **named_params) - instance = self._mox.CreateMock(self._class_to_mock) - self._instance_queue.appendleft(instance) - return instance + instance = self._mox.CreateMock(self._class_to_mock) + self._instance_queue.appendleft(instance) + return instance - def _Verify(self): - """Verify that all mocks have been created.""" - if self._instance_queue: - raise ExpectedMockCreationError(self._instance_queue) - super(_MockObjectFactory, self)._Verify() + def _Verify(self): + """Verify that all mocks have been created.""" + if self._instance_queue: + raise ExpectedMockCreationError(self._instance_queue) + super(_MockObjectFactory, self)._Verify() class MethodSignatureChecker(object): - """Ensures that methods are called correctly.""" + """Ensures that methods are called correctly.""" - _NEEDED, _DEFAULT, _GIVEN = range(3) + _NEEDED, _DEFAULT, _GIVEN = range(3) - def __init__(self, method, class_to_bind=None): - """Creates a checker. + def __init__(self, method, class_to_bind=None): + """Creates a checker. - Args: - # method: A method to check. - # class_to_bind: optionally, a class used to type check first method - # parameter, only used with unbound methods - method: function - class_to_bind: type or None + Args: + # method: A method to check. + # class_to_bind: optionally, a class used to type check first method + # parameter, only used with unbound methods + method: function + class_to_bind: type or None - Raises: - ValueError: method could not be inspected, so checks aren't possible. - Some methods and functions like built-ins can't be inspected. - """ - try: - self._args, varargs, varkw, defaults = inspect.getargspec(method) - except TypeError: - raise ValueError('Could not get argument specification for %r' - % (method,)) - if inspect.ismethod(method) or class_to_bind: - self._args = self._args[1:] # Skip 'self'. - self._method = method - self._instance = None # May contain the instance this is bound to. - self._instance = getattr(method, "__self__", None) - - # _bounded_to determines whether the method is bound or not - if self._instance: - self._bounded_to = self._instance.__class__ - else: - self._bounded_to = class_to_bind or getattr(method, "im_class", None) - - self._has_varargs = varargs is not None - self._has_varkw = varkw is not None - if defaults is None: - self._required_args = self._args - self._default_args = [] - else: - self._required_args = self._args[:-len(defaults)] - self._default_args = self._args[-len(defaults):] - - def _RecordArgumentGiven(self, arg_name, arg_status): - """Mark an argument as being given. - - Args: - # arg_name: The name of the argument to mark in arg_status. - # arg_status: Maps argument names to one of _NEEDED, _DEFAULT, _GIVEN. - arg_name: string - arg_status: dict - - Raises: - AttributeError: arg_name is already marked as _GIVEN. - """ - if arg_status.get(arg_name, None) == MethodSignatureChecker._GIVEN: - raise AttributeError('%s provided more than once' % (arg_name,)) - arg_status[arg_name] = MethodSignatureChecker._GIVEN - - def Check(self, params, named_params): - """Ensures that the parameters used while recording a call are valid. - - Args: - # params: A list of positional parameters. - # named_params: A dict of named parameters. - params: list - named_params: dict - - Raises: - AttributeError: the given parameters don't work with the given method. - """ - arg_status = dict((a, MethodSignatureChecker._NEEDED) - for a in self._required_args) - for arg in self._default_args: - arg_status[arg] = MethodSignatureChecker._DEFAULT - - # WARNING: Suspect hack ahead. - # - # Check to see if this is an unbound method, where the instance - # should be bound as the first argument. We try to determine if - # the first argument (param[0]) is an instance of the class, or it - # is equivalent to the class (used to account for Comparators). - # - # NOTE: If a Func() comparator is used, and the signature is not - # correct, this will cause extra executions of the function. - if inspect.ismethod(self._method) or self._bounded_to: - # The extra param accounts for the bound instance. - if len(params) > len(self._required_args): - expected = self._bounded_to - - # Check if the param is an instance of the expected class, - # or check equality (useful for checking Comparators). - - # This is a hack to work around the fact that the first - # parameter can be a Comparator, and the comparison may raise - # an exception during this comparison, which is OK. + Raises: + ValueError: method could not be inspected, so checks aren't possible. + Some methods and functions like built-ins can't be inspected. + """ try: - param_equality = (params[0] == expected) - except: - param_equality = False + self._args, varargs, varkw, defaults = inspect.getargspec(method) + except TypeError: + raise ValueError('Could not get argument specification for %r' + % (method,)) + if inspect.ismethod(method) or class_to_bind: + self._args = self._args[1:] # Skip 'self'. + self._method = method + self._instance = None # May contain the instance this is bound to. + self._instance = getattr(method, "__self__", None) - if isinstance(params[0], expected) or param_equality: - params = params[1:] - # If the IsA() comparator is being used, we need to check the - # inverse of the usual case - that the given instance is a subclass - # of the expected class. For example, the code under test does - # late binding to a subclass. - elif isinstance(params[0], IsA) and params[0]._IsSubClass(expected): - params = params[1:] + # _bounded_to determines whether the method is bound or not + if self._instance: + self._bounded_to = self._instance.__class__ + else: + self._bounded_to = class_to_bind or getattr(method, "im_class", None) - # Check that each positional param is valid. - for i in range(len(params)): - try: - arg_name = self._args[i] - except IndexError: - if not self._has_varargs: - raise AttributeError('%s does not take %d or more positional ' - 'arguments' % (self._method.__name__, i)) - else: - self._RecordArgumentGiven(arg_name, arg_status) + self._has_varargs = varargs is not None + self._has_varkw = varkw is not None + if defaults is None: + self._required_args = self._args + self._default_args = [] + else: + self._required_args = self._args[:-len(defaults)] + self._default_args = self._args[-len(defaults):] - # Check each keyword argument. - for arg_name in named_params: - if arg_name not in arg_status and not self._has_varkw: - raise AttributeError('%s is not expecting keyword argument %s' - % (self._method.__name__, arg_name)) - self._RecordArgumentGiven(arg_name, arg_status) + def _RecordArgumentGiven(self, arg_name, arg_status): + """Mark an argument as being given. - # Ensure all the required arguments have been given. - still_needed = [k for k, v in arg_status.items() - if v == MethodSignatureChecker._NEEDED] - if still_needed: - raise AttributeError('No values given for arguments: %s' - % (' '.join(sorted(still_needed)))) + Args: + # arg_name: The name of the argument to mark in arg_status. + # arg_status: Maps argument names to one of _NEEDED, _DEFAULT, _GIVEN. + arg_name: string + arg_status: dict + + Raises: + AttributeError: arg_name is already marked as _GIVEN. + """ + if arg_status.get(arg_name, None) == MethodSignatureChecker._GIVEN: + raise AttributeError('%s provided more than once' % (arg_name,)) + arg_status[arg_name] = MethodSignatureChecker._GIVEN + + def Check(self, params, named_params): + """Ensures that the parameters used while recording a call are valid. + + Args: + # params: A list of positional parameters. + # named_params: A dict of named parameters. + params: list + named_params: dict + + Raises: + AttributeError: the given parameters don't work with the given method. + """ + arg_status = dict((a, MethodSignatureChecker._NEEDED) + for a in self._required_args) + for arg in self._default_args: + arg_status[arg] = MethodSignatureChecker._DEFAULT + + # WARNING: Suspect hack ahead. + # + # Check to see if this is an unbound method, where the instance + # should be bound as the first argument. We try to determine if + # the first argument (param[0]) is an instance of the class, or it + # is equivalent to the class (used to account for Comparators). + # + # NOTE: If a Func() comparator is used, and the signature is not + # correct, this will cause extra executions of the function. + if inspect.ismethod(self._method) or self._bounded_to: + # The extra param accounts for the bound instance. + if len(params) > len(self._required_args): + expected = self._bounded_to + + # Check if the param is an instance of the expected class, + # or check equality (useful for checking Comparators). + + # This is a hack to work around the fact that the first + # parameter can be a Comparator, and the comparison may raise + # an exception during this comparison, which is OK. + try: + param_equality = (params[0] == expected) + except: + param_equality = False + + if isinstance(params[0], expected) or param_equality: + params = params[1:] + # If the IsA() comparator is being used, we need to check the + # inverse of the usual case - that the given instance is a subclass + # of the expected class. For example, the code under test does + # late binding to a subclass. + elif isinstance(params[0], IsA) and params[0]._IsSubClass(expected): + params = params[1:] + + # Check that each positional param is valid. + for i in range(len(params)): + try: + arg_name = self._args[i] + except IndexError: + if not self._has_varargs: + raise AttributeError('%s does not take %d or more positional ' + 'arguments' % (self._method.__name__, i)) + else: + self._RecordArgumentGiven(arg_name, arg_status) + + # Check each keyword argument. + for arg_name in named_params: + if arg_name not in arg_status and not self._has_varkw: + raise AttributeError('%s is not expecting keyword argument %s' + % (self._method.__name__, arg_name)) + self._RecordArgumentGiven(arg_name, arg_status) + + # Ensure all the required arguments have been given. + still_needed = [k for k, v in arg_status.items() + if v == MethodSignatureChecker._NEEDED] + if still_needed: + raise AttributeError('No values given for arguments: %s' + % (' '.join(sorted(still_needed)))) class MockMethod(object): - """Callable mock method. + """Callable mock method. - A MockMethod should act exactly like the method it mocks, accepting - parameters and returning a value, or throwing an exception (as specified). - When this method is called, it can optionally verify whether the called - method (name and signature) matches the expected method. - """ - - def __init__(self, method_name, call_queue, replay_mode, - method_to_mock=None, description=None, class_to_bind=None): - """Construct a new mock method. - - Args: - # method_name: the name of the method - # call_queue: deque of calls, verify this call against the head, or add - # this call to the queue. - # replay_mode: False if we are recording, True if we are verifying calls - # against the call queue. - # method_to_mock: The actual method being mocked, used for introspection. - # description: optionally, a descriptive name for this method. Typically - # this is equal to the descriptive name of the method's class. - # class_to_bind: optionally, a class that is used for unbound methods - # (or functions in Python3) to which method is bound, in order not - # to loose binding information. If given, it will be used for - # checking the type of first method parameter - method_name: str - call_queue: list or deque - replay_mode: bool - method_to_mock: a method object - description: str or None - class_to_bind: type or None + A MockMethod should act exactly like the method it mocks, accepting + parameters and returning a value, or throwing an exception (as specified). + When this method is called, it can optionally verify whether the called + method (name and signature) matches the expected method. """ - self._name = method_name - self.__name__ = method_name - self._call_queue = call_queue - if not isinstance(call_queue, deque): - self._call_queue = deque(self._call_queue) - self._replay_mode = replay_mode - self._description = description + def __init__(self, method_name, call_queue, replay_mode, + method_to_mock=None, description=None, class_to_bind=None): + """Construct a new mock method. - self._params = None - self._named_params = None - self._return_value = None - self._exception = None - self._side_effects = None + Args: + # method_name: the name of the method + # call_queue: deque of calls, verify this call against the head, or add + # this call to the queue. + # replay_mode: False if we are recording, True if we are verifying calls + # against the call queue. + # method_to_mock: The actual method being mocked, used for introspection. + # description: optionally, a descriptive name for this method. Typically + # this is equal to the descriptive name of the method's class. + # class_to_bind: optionally, a class that is used for unbound methods + # (or functions in Python3) to which method is bound, in order not + # to loose binding information. If given, it will be used for + # checking the type of first method parameter + method_name: str + call_queue: list or deque + replay_mode: bool + method_to_mock: a method object + description: str or None + class_to_bind: type or None + """ - try: - self._checker = MethodSignatureChecker(method_to_mock, - class_to_bind=class_to_bind) - except ValueError: - self._checker = None + self._name = method_name + self.__name__ = method_name + self._call_queue = call_queue + if not isinstance(call_queue, deque): + self._call_queue = deque(self._call_queue) + self._replay_mode = replay_mode + self._description = description - def __call__(self, *params, **named_params): - """Log parameters and return the specified return value. + self._params = None + self._named_params = None + self._return_value = None + self._exception = None + self._side_effects = None - If the Mock(Anything/Object) associated with this call is in record mode, - this MockMethod will be pushed onto the expected call queue. If the mock - is in replay mode, this will pop a MockMethod off the top of the queue and - verify this call is equal to the expected call. + try: + self._checker = MethodSignatureChecker(method_to_mock, + class_to_bind=class_to_bind) + except ValueError: + self._checker = None - Raises: - UnexpectedMethodCall if this call is supposed to match an expected method - call and it does not. - """ + def __call__(self, *params, **named_params): + """Log parameters and return the specified return value. - self._params = params - self._named_params = named_params + If the Mock(Anything/Object) associated with this call is in record mode, + this MockMethod will be pushed onto the expected call queue. If the mock + is in replay mode, this will pop a MockMethod off the top of the queue and + verify this call is equal to the expected call. - if not self._replay_mode: - if self._checker is not None: - self._checker.Check(params, named_params) - self._call_queue.append(self) - return self + Raises: + UnexpectedMethodCall if this call is supposed to match an expected method + call and it does not. + """ - expected_method = self._VerifyMethodCall() + self._params = params + self._named_params = named_params - if expected_method._side_effects: - result = expected_method._side_effects(*params, **named_params) - if expected_method._return_value is None: - expected_method._return_value = result + if not self._replay_mode: + if self._checker is not None: + self._checker.Check(params, named_params) + self._call_queue.append(self) + return self - if expected_method._exception: - raise expected_method._exception + expected_method = self._VerifyMethodCall() - return expected_method._return_value + if expected_method._side_effects: + result = expected_method._side_effects(*params, **named_params) + if expected_method._return_value is None: + expected_method._return_value = result - def __getattr__(self, name): - """Raise an AttributeError with a helpful message.""" + if expected_method._exception: + raise expected_method._exception - raise AttributeError('MockMethod has no attribute "%s". ' - 'Did you remember to put your mocks in replay mode?' % name) + return expected_method._return_value - def __iter__(self): - """Raise a TypeError with a helpful message.""" - raise TypeError('MockMethod cannot be iterated. ' - 'Did you remember to put your mocks in replay mode?') + def __getattr__(self, name): + """Raise an AttributeError with a helpful message.""" - def next(self): - """Raise a TypeError with a helpful message.""" - raise TypeError('MockMethod cannot be iterated. ' - 'Did you remember to put your mocks in replay mode?') + raise AttributeError('MockMethod has no attribute "%s". ' + 'Did you remember to put your mocks in replay mode?' % name) - def __next__(self): - """Raise a TypeError with a helpful message.""" - raise TypeError('MockMethod cannot be iterated. ' - 'Did you remember to put your mocks in replay mode?') + def __iter__(self): + """Raise a TypeError with a helpful message.""" + raise TypeError('MockMethod cannot be iterated. ' + 'Did you remember to put your mocks in replay mode?') - def _PopNextMethod(self): - """Pop the next method from our call queue.""" - try: - return self._call_queue.popleft() - except IndexError: - raise UnexpectedMethodCallError(self, None) + def next(self): + """Raise a TypeError with a helpful message.""" + raise TypeError('MockMethod cannot be iterated. ' + 'Did you remember to put your mocks in replay mode?') - def _VerifyMethodCall(self): - """Verify the called method is expected. + def __next__(self): + """Raise a TypeError with a helpful message.""" + raise TypeError('MockMethod cannot be iterated. ' + 'Did you remember to put your mocks in replay mode?') - This can be an ordered method, or part of an unordered set. + def _PopNextMethod(self): + """Pop the next method from our call queue.""" + try: + return self._call_queue.popleft() + except IndexError: + raise UnexpectedMethodCallError(self, None) - Returns: - The expected mock method. + def _VerifyMethodCall(self): + """Verify the called method is expected. - Raises: - UnexpectedMethodCall if the method called was not expected. - """ + This can be an ordered method, or part of an unordered set. - expected = self._PopNextMethod() + Returns: + The expected mock method. - # Loop here, because we might have a MethodGroup followed by another - # group. - while isinstance(expected, MethodGroup): - expected, method = expected.MethodCalled(self) - if method is not None: - return method + Raises: + UnexpectedMethodCall if the method called was not expected. + """ - # This is a mock method, so just check equality. - if expected != self: - raise UnexpectedMethodCallError(self, expected) + expected = self._PopNextMethod() - return expected + # Loop here, because we might have a MethodGroup followed by another + # group. + while isinstance(expected, MethodGroup): + expected, method = expected.MethodCalled(self) + if method is not None: + return method - def __str__(self): - params = ', '.join( - [repr(p) for p in self._params or []] + - ['%s=%r' % x for x in sorted((self._named_params or {}).items())]) - full_desc = "%s(%s) -> %r" % (self._name, params, self._return_value) - if self._description: - full_desc = "%s.%s" % (self._description, full_desc) - return full_desc + # This is a mock method, so just check equality. + if expected != self: + raise UnexpectedMethodCallError(self, expected) - def __hash__(self): - return id(self) + return expected - def __eq__(self, rhs): - """Test whether this MockMethod is equivalent to another MockMethod. + def __str__(self): + params = ', '.join( + [repr(p) for p in self._params or []] + + ['%s=%r' % x for x in sorted((self._named_params or {}).items())]) + full_desc = "%s(%s) -> %r" % (self._name, params, self._return_value) + if self._description: + full_desc = "%s.%s" % (self._description, full_desc) + return full_desc - Args: - # rhs: the right hand side of the test - rhs: MockMethod - """ + def __hash__(self): + return id(self) - return (isinstance(rhs, MockMethod) and - self._name == rhs._name and - self._params == rhs._params and - self._named_params == rhs._named_params) + def __eq__(self, rhs): + """Test whether this MockMethod is equivalent to another MockMethod. - def __ne__(self, rhs): - """Test whether this MockMethod is not equivalent to another MockMethod. + Args: + # rhs: the right hand side of the test + rhs: MockMethod + """ - Args: - # rhs: the right hand side of the test - rhs: MockMethod - """ + return (isinstance(rhs, MockMethod) and + self._name == rhs._name and + self._params == rhs._params and + self._named_params == rhs._named_params) - return not self == rhs + def __ne__(self, rhs): + """Test whether this MockMethod is not equivalent to another MockMethod. - def GetPossibleGroup(self): - """Returns a possible group from the end of the call queue or None if no - other methods are on the stack. - """ + Args: + # rhs: the right hand side of the test + rhs: MockMethod + """ - # Remove this method from the tail of the queue so we can add it - # to a group. - this_method = self._call_queue.pop() - assert this_method == self + return not self == rhs - # Determine if the tail of the queue is a group, or just a regular ordered - # mock method. - group = None - try: - group = self._call_queue[-1] - except IndexError: - pass + def GetPossibleGroup(self): + """Returns a possible group from the end of the call queue or None if no + other methods are on the stack. + """ - return group + # Remove this method from the tail of the queue so we can add it + # to a group. + this_method = self._call_queue.pop() + assert this_method == self - def _CheckAndCreateNewGroup(self, group_name, group_class): - """Checks if the last method (a possible group) is an instance of our - group_class. Adds the current method to this group or creates a new one. + # Determine if the tail of the queue is a group, or just a regular ordered + # mock method. + group = None + try: + group = self._call_queue[-1] + except IndexError: + pass - Args: + return group - group_name: the name of the group. - group_class: the class used to create instance of this new group - """ - group = self.GetPossibleGroup() + def _CheckAndCreateNewGroup(self, group_name, group_class): + """Checks if the last method (a possible group) is an instance of our + group_class. Adds the current method to this group or creates a new one. - # If this is a group, and it is the correct group, add the method. - if isinstance(group, group_class) and group.group_name() == group_name: - group.AddMethod(self) - return self + Args: - # Create a new group and add the method. - new_group = group_class(group_name) - new_group.AddMethod(self) - self._call_queue.append(new_group) - return self + group_name: the name of the group. + group_class: the class used to create instance of this new group + """ + group = self.GetPossibleGroup() - def InAnyOrder(self, group_name="default"): - """Move this method into a group of unordered calls. + # If this is a group, and it is the correct group, add the method. + if isinstance(group, group_class) and group.group_name() == group_name: + group.AddMethod(self) + return self - A group of unordered calls must be defined together, and must be executed - in full before the next expected method can be called. There can be - multiple groups that are expected serially, if they are given - different group names. The same group name can be reused if there is a - standard method call, or a group with a different name, spliced between - usages. + # Create a new group and add the method. + new_group = group_class(group_name) + new_group.AddMethod(self) + self._call_queue.append(new_group) + return self - Args: - group_name: the name of the unordered group. + def InAnyOrder(self, group_name="default"): + """Move this method into a group of unordered calls. - Returns: - self - """ - return self._CheckAndCreateNewGroup(group_name, UnorderedGroup) + A group of unordered calls must be defined together, and must be executed + in full before the next expected method can be called. There can be + multiple groups that are expected serially, if they are given + different group names. The same group name can be reused if there is a + standard method call, or a group with a different name, spliced between + usages. - def MultipleTimes(self, group_name="default"): - """Move this method into group of calls which may be called multiple times. + Args: + group_name: the name of the unordered group. - A group of repeating calls must be defined together, and must be executed - in full before the next expected method can be called. + Returns: + self + """ + return self._CheckAndCreateNewGroup(group_name, UnorderedGroup) - Args: - group_name: the name of the unordered group. + def MultipleTimes(self, group_name="default"): + """Move this method into group of calls which may be called multiple times. - Returns: - self - """ - return self._CheckAndCreateNewGroup(group_name, MultipleTimesGroup) + A group of repeating calls must be defined together, and must be executed + in full before the next expected method can be called. - def AndReturn(self, return_value): - """Set the value to return when this method is called. + Args: + group_name: the name of the unordered group. - Args: - # return_value can be anything. - """ + Returns: + self + """ + return self._CheckAndCreateNewGroup(group_name, MultipleTimesGroup) - self._return_value = return_value - return return_value + def AndReturn(self, return_value): + """Set the value to return when this method is called. - def AndRaise(self, exception): - """Set the exception to raise when this method is called. + Args: + # return_value can be anything. + """ - Args: - # exception: the exception to raise when this method is called. - exception: Exception - """ + self._return_value = return_value + return return_value - self._exception = exception + def AndRaise(self, exception): + """Set the exception to raise when this method is called. - def WithSideEffects(self, side_effects): - """Set the side effects that are simulated when this method is called. + Args: + # exception: the exception to raise when this method is called. + exception: Exception + """ - Args: - side_effects: A callable which modifies the parameters or other relevant - state which a given test case depends on. + self._exception = exception - Returns: - Self for chaining with AndReturn and AndRaise. - """ - self._side_effects = side_effects - return self + def WithSideEffects(self, side_effects): + """Set the side effects that are simulated when this method is called. + + Args: + side_effects: A callable which modifies the parameters or other relevant + state which a given test case depends on. + + Returns: + Self for chaining with AndReturn and AndRaise. + """ + self._side_effects = side_effects + return self class Comparator: - """Base class for all Mox comparators. + """Base class for all Mox comparators. - A Comparator can be used as a parameter to a mocked method when the exact - value is not known. For example, the code you are testing might build up a - long SQL string that is passed to your mock DAO. You're only interested that - the IN clause contains the proper primary keys, so you can set your mock - up as follows: + A Comparator can be used as a parameter to a mocked method when the exact + value is not known. For example, the code you are testing might build up a + long SQL string that is passed to your mock DAO. You're only interested that + the IN clause contains the proper primary keys, so you can set your mock + up as follows: - mock_dao.RunQuery(StrContains('IN (1, 2, 4, 5)')).AndReturn(mock_result) + mock_dao.RunQuery(StrContains('IN (1, 2, 4, 5)')).AndReturn(mock_result) - Now whatever query is passed in must contain the string 'IN (1, 2, 4, 5)'. + Now whatever query is passed in must contain the string 'IN (1, 2, 4, 5)'. - A Comparator may replace one or more parameters, for example: - # return at most 10 rows - mock_dao.RunQuery(StrContains('SELECT'), 10) + A Comparator may replace one or more parameters, for example: + # return at most 10 rows + mock_dao.RunQuery(StrContains('SELECT'), 10) - or + or - # Return some non-deterministic number of rows - mock_dao.RunQuery(StrContains('SELECT'), IsA(int)) - """ - - def equals(self, rhs): - """Special equals method that all comparators must implement. - - Args: - rhs: any python object + # Return some non-deterministic number of rows + mock_dao.RunQuery(StrContains('SELECT'), IsA(int)) """ - raise NotImplementedError('method must be implemented by a subclass.') + def equals(self, rhs): + """Special equals method that all comparators must implement. - def __eq__(self, rhs): - return self.equals(rhs) + Args: + rhs: any python object + """ - def __ne__(self, rhs): - return not self.equals(rhs) + raise NotImplementedError('method must be implemented by a subclass.') + + def __eq__(self, rhs): + return self.equals(rhs) + + def __ne__(self, rhs): + return not self.equals(rhs) class Is(Comparator): - """Comparison class used to check identity, instead of equality.""" + """Comparison class used to check identity, instead of equality.""" - def __init__(self, obj): - self._obj = obj + def __init__(self, obj): + self._obj = obj - def equals(self, rhs): - return rhs is self._obj + def equals(self, rhs): + return rhs is self._obj - def __repr__(self): - return "" % (self._obj, id(self._obj)) + def __repr__(self): + return "" % (self._obj, id(self._obj)) class IsA(Comparator): - """This class wraps a basic Python type or class. It is used to verify - that a parameter is of the given type or class. + """This class wraps a basic Python type or class. It is used to verify + that a parameter is of the given type or class. - Example: - mock_dao.Connect(IsA(DbConnectInfo)) - """ - - def __init__(self, class_name): - """Initialize IsA - - Args: - class_name: basic python type or a class + Example: + mock_dao.Connect(IsA(DbConnectInfo)) """ - self._class_name = class_name + def __init__(self, class_name): + """Initialize IsA - def equals(self, rhs): - """Check to see if the RHS is an instance of class_name. + Args: + class_name: basic python type or a class + """ - Args: - # rhs: the right hand side of the test - rhs: object + self._class_name = class_name - Returns: - bool - """ + def equals(self, rhs): + """Check to see if the RHS is an instance of class_name. - try: - return isinstance(rhs, self._class_name) - except TypeError: - # Check raw types if there was a type error. This is helpful for - # things like cStringIO.StringIO. - return type(rhs) == type(self._class_name) + Args: + # rhs: the right hand side of the test + rhs: object - def _IsSubClass(self, clazz): - """Check to see if the IsA comparators class is a subclass of clazz. + Returns: + bool + """ - Args: - # clazz: a class object + try: + return isinstance(rhs, self._class_name) + except TypeError: + # Check raw types if there was a type error. This is helpful for + # things like cStringIO.StringIO. + return type(rhs) == type(self._class_name) - Returns: - bool - """ + def _IsSubClass(self, clazz): + """Check to see if the IsA comparators class is a subclass of clazz. - try: - return issubclass(self._class_name, clazz) - except TypeError: - # Check raw types if there was a type error. This is helpful for - # things like cStringIO.StringIO. - return type(clazz) == type(self._class_name) + Args: + # clazz: a class object - def __repr__(self): - return 'mox.IsA(%s) ' % str(self._class_name) + Returns: + bool + """ + + try: + return issubclass(self._class_name, clazz) + except TypeError: + # Check raw types if there was a type error. This is helpful for + # things like cStringIO.StringIO. + return type(clazz) == type(self._class_name) + + def __repr__(self): + return 'mox.IsA(%s) ' % str(self._class_name) class IsAlmost(Comparator): - """Comparison class used to check whether a parameter is nearly equal - to a given value. Generally useful for floating point numbers. + """Comparison class used to check whether a parameter is nearly equal + to a given value. Generally useful for floating point numbers. - Example mock_dao.SetTimeout((IsAlmost(3.9))) - """ - - def __init__(self, float_value, places=7): - """Initialize IsAlmost. - - Args: - float_value: The value for making the comparison. - places: The number of decimal places to round to. + Example mock_dao.SetTimeout((IsAlmost(3.9))) """ - self._float_value = float_value - self._places = places + def __init__(self, float_value, places=7): + """Initialize IsAlmost. - def equals(self, rhs): - """Check to see if RHS is almost equal to float_value + Args: + float_value: The value for making the comparison. + places: The number of decimal places to round to. + """ - Args: - rhs: the value to compare to float_value + self._float_value = float_value + self._places = places - Returns: - bool - """ + def equals(self, rhs): + """Check to see if RHS is almost equal to float_value - try: - return round(rhs - self._float_value, self._places) == 0 - except Exception: - # This is probably because either float_value or rhs is not a number. - return False + Args: + rhs: the value to compare to float_value - def __repr__(self): - return str(self._float_value) + Returns: + bool + """ + + try: + return round(rhs - self._float_value, self._places) == 0 + except Exception: + # This is probably because either float_value or rhs is not a number. + return False + + def __repr__(self): + return str(self._float_value) class StrContains(Comparator): - """Comparison class used to check whether a substring exists in a - string parameter. This can be useful in mocking a database with SQL - passed in as a string parameter, for example. + """Comparison class used to check whether a substring exists in a + string parameter. This can be useful in mocking a database with SQL + passed in as a string parameter, for example. - Example: - mock_dao.RunQuery(StrContains('IN (1, 2, 4, 5)')).AndReturn(mock_result) - """ - - def __init__(self, search_string): - """Initialize. - - Args: - # search_string: the string you are searching for - search_string: str + Example: + mock_dao.RunQuery(StrContains('IN (1, 2, 4, 5)')).AndReturn(mock_result) """ - self._search_string = search_string + def __init__(self, search_string): + """Initialize. - def equals(self, rhs): - """Check to see if the search_string is contained in the rhs string. + Args: + # search_string: the string you are searching for + search_string: str + """ - Args: - # rhs: the right hand side of the test - rhs: object + self._search_string = search_string - Returns: - bool - """ + def equals(self, rhs): + """Check to see if the search_string is contained in the rhs string. - try: - return rhs.find(self._search_string) > -1 - except Exception: - return False + Args: + # rhs: the right hand side of the test + rhs: object - def __repr__(self): - return '' % self._search_string + Returns: + bool + """ + + try: + return rhs.find(self._search_string) > -1 + except Exception: + return False + + def __repr__(self): + return '' % self._search_string class Regex(Comparator): - """Checks if a string matches a regular expression. + """Checks if a string matches a regular expression. - This uses a given regular expression to determine equality. - """ - - def __init__(self, pattern, flags=0): - """Initialize. - - Args: - # pattern is the regular expression to search for - pattern: str - # flags passed to re.compile function as the second argument - flags: int - """ - self.flags = flags - self.regex = re.compile(pattern, flags=flags) - - def equals(self, rhs): - """Check to see if rhs matches regular expression pattern. - - Returns: - bool + This uses a given regular expression to determine equality. """ - try: - return self.regex.search(rhs) is not None - except Exception: - return False + def __init__(self, pattern, flags=0): + """Initialize. - def __repr__(self): - s = '' % str(self._key) + Returns: + bool + """ + + try: + return self._key in rhs + except Exception: + return False + + def __repr__(self): + return '' % str(self._key) class Not(Comparator): - """Checks whether a predicates is False. + """Checks whether a predicates is False. - Example: - mock_dao.UpdateUsers(Not(ContainsKeyValue('stevepm', stevepm_user_info))) - """ - - def __init__(self, predicate): - """Initialize. - - Args: - # predicate: a Comparator instance. + Example: + mock_dao.UpdateUsers(Not(ContainsKeyValue('stevepm', stevepm_user_info))) """ - assert isinstance(predicate, Comparator), ("predicate %r must be a" - " Comparator." % predicate) - self._predicate = predicate + def __init__(self, predicate): + """Initialize. - def equals(self, rhs): - """Check to see whether the predicate is False. + Args: + # predicate: a Comparator instance. + """ - Args: - rhs: A value that will be given in argument of the predicate. + assert isinstance(predicate, Comparator), ("predicate %r must be a" + " Comparator." % predicate) + self._predicate = predicate - Returns: - bool - """ + def equals(self, rhs): + """Check to see whether the predicate is False. - try: - return not self._predicate.equals(rhs) - except Exception: - return False + Args: + rhs: A value that will be given in argument of the predicate. - def __repr__(self): - return '' % self._predicate + Returns: + bool + """ + + try: + return not self._predicate.equals(rhs) + except Exception: + return False + + def __repr__(self): + return '' % self._predicate class ContainsKeyValue(Comparator): - """Checks whether a key/value pair is in a dict parameter. + """Checks whether a key/value pair is in a dict parameter. - Example: - mock_dao.UpdateUsers(ContainsKeyValue('stevepm', stevepm_user_info)) - """ - - def __init__(self, key, value): - """Initialize. - - Args: - # key: a key in a dict - # value: the corresponding value + Example: + mock_dao.UpdateUsers(ContainsKeyValue('stevepm', stevepm_user_info)) """ - self._key = key - self._value = value + def __init__(self, key, value): + """Initialize. - def equals(self, rhs): - """Check whether the given key/value pair is in the rhs dict. + Args: + # key: a key in a dict + # value: the corresponding value + """ - Returns: - bool - """ + self._key = key + self._value = value - try: - return rhs[self._key] == self._value - except Exception: - return False + def equals(self, rhs): + """Check whether the given key/value pair is in the rhs dict. - def __repr__(self): - return '' % (str(self._key), - str(self._value)) + Returns: + bool + """ + + try: + return rhs[self._key] == self._value + except Exception: + return False + + def __repr__(self): + return '' % (str(self._key), + str(self._value)) class ContainsAttributeValue(Comparator): - """Checks whether a passed parameter contains attributes with a given value. + """Checks whether a passed parameter contains attributes with a given value. - Example: - mock_dao.UpdateSomething(ContainsAttribute('stevepm', stevepm_user_info)) - """ - - def __init__(self, key, value): - """Initialize. - - Args: - # key: an attribute name of an object - # value: the corresponding value + Example: + mock_dao.UpdateSomething(ContainsAttribute('stevepm', stevepm_user_info)) """ - self._key = key - self._value = value + def __init__(self, key, value): + """Initialize. - def equals(self, rhs): - """Check if the given attribute has a matching value in the rhs object. + Args: + # key: an attribute name of an object + # value: the corresponding value + """ - Returns: - bool - """ + self._key = key + self._value = value - try: - return getattr(rhs, self._key) == self._value - except Exception: - return False + def equals(self, rhs): + """Check if the given attribute has a matching value in the rhs object. + + Returns: + bool + """ + + try: + return getattr(rhs, self._key) == self._value + except Exception: + return False class SameElementsAs(Comparator): - """Checks whether sequences contain the same elements (ignoring order). + """Checks whether sequences contain the same elements (ignoring order). - Example: - mock_dao.ProcessUsers(SameElementsAs('stevepm', 'salomaki')) - """ - - def __init__(self, expected_seq): - """Initialize. - - Args: - expected_seq: a sequence + Example: + mock_dao.ProcessUsers(SameElementsAs('stevepm', 'salomaki')) """ - # Store in case expected_seq is an iterator. - self._expected_list = list(expected_seq) - def equals(self, actual_seq): - """Check to see whether actual_seq has same elements as expected_seq. + def __init__(self, expected_seq): + """Initialize. - Args: - actual_seq: sequence + Args: + expected_seq: a sequence + """ + # Store in case expected_seq is an iterator. + self._expected_list = list(expected_seq) - Returns: - bool - """ - try: - # Store in case actual_seq is an iterator. We potentially iterate twice: - # once to make the dict, once in the list fallback. - actual_list = list(actual_seq) - except TypeError: - # actual_seq cannot be read as a sequence. - # - # This happens because Mox uses __eq__ both to check object equality (in - # MethodSignatureChecker) and to invoke Comparators. - return False + def equals(self, actual_seq): + """Check to see whether actual_seq has same elements as expected_seq. - try: - return set(self._expected_list) == set(actual_list) - except TypeError: - # Fall back to slower list-compare if any of the objects are unhashable. - if len(self._expected_list) != len(actual_list): - return False - for el in actual_list: - if el not in self._expected_list: - return False - return True + Args: + actual_seq: sequence - def __repr__(self): - return '' % self._expected_list + Returns: + bool + """ + try: + # Store in case actual_seq is an iterator. We potentially iterate twice: + # once to make the dict, once in the list fallback. + actual_list = list(actual_seq) + except TypeError: + # actual_seq cannot be read as a sequence. + # + # This happens because Mox uses __eq__ both to check object equality (in + # MethodSignatureChecker) and to invoke Comparators. + return False + + try: + return set(self._expected_list) == set(actual_list) + except TypeError: + # Fall back to slower list-compare if any of the objects are unhashable. + if len(self._expected_list) != len(actual_list): + return False + for el in actual_list: + if el not in self._expected_list: + return False + return True + + def __repr__(self): + return '' % self._expected_list class And(Comparator): - """Evaluates one or more Comparators on RHS, returns an AND of the results. - """ - - def __init__(self, *args): - """Initialize. - - Args: - *args: One or more Comparator + """Evaluates one or more Comparators on RHS, returns an AND of the results. """ - self._comparators = args + def __init__(self, *args): + """Initialize. - def equals(self, rhs): - """Checks whether all Comparators are equal to rhs. + Args: + *args: One or more Comparator + """ - Args: - # rhs: can be anything + self._comparators = args - Returns: - bool - """ + def equals(self, rhs): + """Checks whether all Comparators are equal to rhs. - for comparator in self._comparators: - if not comparator.equals(rhs): - return False + Args: + # rhs: can be anything - return True + Returns: + bool + """ - def __repr__(self): - return '' % str(self._comparators) + for comparator in self._comparators: + if not comparator.equals(rhs): + return False + + return True + + def __repr__(self): + return '' % str(self._comparators) class Or(Comparator): - """Evaluates one or more Comparators on RHS and returns an OR of the results. - """ - - def __init__(self, *args): - """Initialize. - - Args: - *args: One or more Mox comparators + """Evaluates one or more Comparators on RHS and returns an OR of the results. """ - self._comparators = args + def __init__(self, *args): + """Initialize. - def equals(self, rhs): - """Checks whether any Comparator is equal to rhs. + Args: + *args: One or more Mox comparators + """ - Args: - # rhs: can be anything + self._comparators = args - Returns: - bool - """ + def equals(self, rhs): + """Checks whether any Comparator is equal to rhs. - for comparator in self._comparators: - if comparator.equals(rhs): - return True + Args: + # rhs: can be anything - return False + Returns: + bool + """ - def __repr__(self): - return '' % str(self._comparators) + for comparator in self._comparators: + if comparator.equals(rhs): + return True + + return False + + def __repr__(self): + return '' % str(self._comparators) class Func(Comparator): - """Call a function that should verify the parameter passed in is correct. + """Call a function that should verify the parameter passed in is correct. - You may need the ability to perform more advanced operations on the parameter - in order to validate it. You can use this to have a callable validate any - parameter. The callable should return either True or False. + You may need the ability to perform more advanced operations on the parameter + in order to validate it. You can use this to have a callable validate any + parameter. The callable should return either True or False. - Example: + Example: - def myParamValidator(param): - # Advanced logic here - return True + def myParamValidator(param): + # Advanced logic here + return True - mock_dao.DoSomething(Func(myParamValidator), true) - """ - - def __init__(self, func): - """Initialize. - - Args: - func: callable that takes one parameter and returns a bool + mock_dao.DoSomething(Func(myParamValidator), true) """ - self._func = func + def __init__(self, func): + """Initialize. - def equals(self, rhs): - """Test whether rhs passes the function test. + Args: + func: callable that takes one parameter and returns a bool + """ - rhs is passed into func. + self._func = func - Args: - rhs: any python object + def equals(self, rhs): + """Test whether rhs passes the function test. - Returns: - the result of func(rhs) - """ + rhs is passed into func. - return self._func(rhs) + Args: + rhs: any python object - def __repr__(self): - return str(self._func) + Returns: + the result of func(rhs) + """ + + return self._func(rhs) + + def __repr__(self): + return str(self._func) class IgnoreArg(Comparator): - """Ignore an argument. + """Ignore an argument. - This can be used when we don't care about an argument of a method call. + This can be used when we don't care about an argument of a method call. - Example: - # Check if CastMagic is called with 3 as first arg and 'disappear' as third. - mymock.CastMagic(3, IgnoreArg(), 'disappear') - """ - - def equals(self, unused_rhs): - """Ignores arguments and returns True. - - Args: - unused_rhs: any python object - - Returns: - always returns True + Example: + # Check if CastMagic is called with 3 as first arg and 'disappear' as third. + mymock.CastMagic(3, IgnoreArg(), 'disappear') """ - return True + def equals(self, unused_rhs): + """Ignores arguments and returns True. - def __repr__(self): - return '' + Args: + unused_rhs: any python object + + Returns: + always returns True + """ + + return True + + def __repr__(self): + return '' class Value(Comparator): - """Compares argument against a remembered value. + """Compares argument against a remembered value. - To be used in conjunction with Remember comparator. See Remember() - for example. - """ + To be used in conjunction with Remember comparator. See Remember() + for example. + """ - def __init__(self): - self._value = None - self._has_value = False + def __init__(self): + self._value = None + self._has_value = False - def store_value(self, rhs): - self._value = rhs - self._has_value = True + def store_value(self, rhs): + self._value = rhs + self._has_value = True - def equals(self, rhs): - if not self._has_value: - return False - else: - return rhs == self._value + def equals(self, rhs): + if not self._has_value: + return False + else: + return rhs == self._value - def __repr__(self): - if self._has_value: - return "" % self._value - else: - return "" + def __repr__(self): + if self._has_value: + return "" % self._value + else: + return "" class Remember(Comparator): - """Remembers the argument to a value store. + """Remembers the argument to a value store. - To be used in conjunction with Value comparator. + To be used in conjunction with Value comparator. - Example: - # Remember the argument for one method call. - users_list = Value() - mock_dao.ProcessUsers(Remember(users_list)) + Example: + # Remember the argument for one method call. + users_list = Value() + mock_dao.ProcessUsers(Remember(users_list)) - # Check argument against remembered value. - mock_dao.ReportUsers(users_list) - """ + # Check argument against remembered value. + mock_dao.ReportUsers(users_list) + """ - def __init__(self, value_store): - if not isinstance(value_store, Value): - raise TypeError("value_store is not an instance of the Value class") - self._value_store = value_store + def __init__(self, value_store): + if not isinstance(value_store, Value): + raise TypeError("value_store is not an instance of the Value class") + self._value_store = value_store - def equals(self, rhs): - self._value_store.store_value(rhs) - return True + def equals(self, rhs): + self._value_store.store_value(rhs) + return True - def __repr__(self): - return "" % id(self._value_store) + def __repr__(self): + return "" % id(self._value_store) class MethodGroup(object): - """Base class containing common behaviour for MethodGroups.""" + """Base class containing common behaviour for MethodGroups.""" - def __init__(self, group_name): - self._group_name = group_name + def __init__(self, group_name): + self._group_name = group_name - def group_name(self): - return self._group_name + def group_name(self): + return self._group_name - def __str__(self): - return '<%s "%s">' % (self.__class__.__name__, self._group_name) + def __str__(self): + return '<%s "%s">' % (self.__class__.__name__, self._group_name) - def AddMethod(self, mock_method): - raise NotImplementedError + def AddMethod(self, mock_method): + raise NotImplementedError - def MethodCalled(self, mock_method): - raise NotImplementedError + def MethodCalled(self, mock_method): + raise NotImplementedError - def IsSatisfied(self): - raise NotImplementedError + def IsSatisfied(self): + raise NotImplementedError class UnorderedGroup(MethodGroup): - """UnorderedGroup holds a set of method calls that may occur in any order. + """UnorderedGroup holds a set of method calls that may occur in any order. - This construct is helpful for non-deterministic events, such as iterating - over the keys of a dict. - """ - - def __init__(self, group_name): - super(UnorderedGroup, self).__init__(group_name) - self._methods = [] - - def __str__(self): - return '%s "%s" pending calls:\n%s' % ( - self.__class__.__name__, - self._group_name, - "\n".join(str(method) for method in self._methods)) - - def AddMethod(self, mock_method): - """Add a method to this group. - - Args: - mock_method: A mock method to be added to this group. + This construct is helpful for non-deterministic events, such as iterating + over the keys of a dict. """ - self._methods.append(mock_method) + def __init__(self, group_name): + super(UnorderedGroup, self).__init__(group_name) + self._methods = [] - def MethodCalled(self, mock_method): - """Remove a method call from the group. + def __str__(self): + return '%s "%s" pending calls:\n%s' % ( + self.__class__.__name__, + self._group_name, + "\n".join(str(method) for method in self._methods)) - If the method is not in the set, an UnexpectedMethodCallError will be - raised. + def AddMethod(self, mock_method): + """Add a method to this group. - Args: - mock_method: a mock method that should be equal to a method in the group. + Args: + mock_method: A mock method to be added to this group. + """ - Returns: - The mock method from the group + self._methods.append(mock_method) - Raises: - UnexpectedMethodCallError if the mock_method was not in the group. - """ + def MethodCalled(self, mock_method): + """Remove a method call from the group. - # Check to see if this method exists, and if so, remove it from the set - # and return it. - for method in self._methods: - if method == mock_method: - # Remove the called mock_method instead of the method in the group. - # The called method will match any comparators when equality is checked - # during removal. The method in the group could pass a comparator to - # another comparator during the equality check. - self._methods.remove(mock_method) + If the method is not in the set, an UnexpectedMethodCallError will be + raised. - # If this group is not empty, put it back at the head of the queue. - if not self.IsSatisfied(): - mock_method._call_queue.appendleft(self) + Args: + mock_method: a mock method that should be equal to a method in the group. - return self, method + Returns: + The mock method from the group - raise UnexpectedMethodCallError(mock_method, self) + Raises: + UnexpectedMethodCallError if the mock_method was not in the group. + """ - def IsSatisfied(self): - """Return True if there are not any methods in this group.""" + # Check to see if this method exists, and if so, remove it from the set + # and return it. + for method in self._methods: + if method == mock_method: + # Remove the called mock_method instead of the method in the group. + # The called method will match any comparators when equality is checked + # during removal. The method in the group could pass a comparator to + # another comparator during the equality check. + self._methods.remove(mock_method) - return len(self._methods) == 0 + # If this group is not empty, put it back at the head of the queue. + if not self.IsSatisfied(): + mock_method._call_queue.appendleft(self) + + return self, method + + raise UnexpectedMethodCallError(mock_method, self) + + def IsSatisfied(self): + """Return True if there are not any methods in this group.""" + + return len(self._methods) == 0 class MultipleTimesGroup(MethodGroup): - """MultipleTimesGroup holds methods that may be called any number of times. + """MultipleTimesGroup holds methods that may be called any number of times. - Note: Each method must be called at least once. + Note: Each method must be called at least once. - This is helpful, if you don't know or care how many times a method is called. - """ - - def __init__(self, group_name): - super(MultipleTimesGroup, self).__init__(group_name) - self._methods = set() - self._methods_left = set() - - def AddMethod(self, mock_method): - """Add a method to this group. - - Args: - mock_method: A mock method to be added to this group. + This is helpful, if you don't know or care how many times a method is called. """ - self._methods.add(mock_method) - self._methods_left.add(mock_method) + def __init__(self, group_name): + super(MultipleTimesGroup, self).__init__(group_name) + self._methods = set() + self._methods_left = set() - def MethodCalled(self, mock_method): - """Remove a method call from the group. + def AddMethod(self, mock_method): + """Add a method to this group. - If the method is not in the set, an UnexpectedMethodCallError will be - raised. + Args: + mock_method: A mock method to be added to this group. + """ - Args: - mock_method: a mock method that should be equal to a method in the group. + self._methods.add(mock_method) + self._methods_left.add(mock_method) - Returns: - The mock method from the group + def MethodCalled(self, mock_method): + """Remove a method call from the group. - Raises: - UnexpectedMethodCallError if the mock_method was not in the group. - """ + If the method is not in the set, an UnexpectedMethodCallError will be + raised. - # Check to see if this method exists, and if so add it to the set of - # called methods. - for method in self._methods: - if method == mock_method: - self._methods_left.discard(method) - # Always put this group back on top of the queue, because we don't know - # when we are done. - mock_method._call_queue.appendleft(self) - return self, method + Args: + mock_method: a mock method that should be equal to a method in the group. - if self.IsSatisfied(): - next_method = mock_method._PopNextMethod() - return next_method, None - else: - raise UnexpectedMethodCallError(mock_method, self) + Returns: + The mock method from the group - def IsSatisfied(self): - """Return True if all methods in this group are called at least once.""" - return len(self._methods_left) == 0 + Raises: + UnexpectedMethodCallError if the mock_method was not in the group. + """ + + # Check to see if this method exists, and if so add it to the set of + # called methods. + for method in self._methods: + if method == mock_method: + self._methods_left.discard(method) + # Always put this group back on top of the queue, because we don't know + # when we are done. + mock_method._call_queue.appendleft(self) + return self, method + + if self.IsSatisfied(): + next_method = mock_method._PopNextMethod() + return next_method, None + else: + raise UnexpectedMethodCallError(mock_method, self) + + def IsSatisfied(self): + """Return True if all methods in this group are called at least once.""" + return len(self._methods_left) == 0 class MoxMetaTestBase(type): - """Metaclass to add mox cleanup and verification to every test. + """Metaclass to add mox cleanup and verification to every test. - As the mox unit testing class is being constructed (MoxTestBase or a - subclass), this metaclass will modify all test functions to call the - CleanUpMox method of the test class after they finish. This means that - unstubbing and verifying will happen for every test with no additional code, - and any failures will result in test failures as opposed to errors. - """ - - def __init__(cls, name, bases, d): - type.__init__(cls, name, bases, d) - - # also get all the attributes from the base classes to account - # for a case when test class is not the immediate child of MoxTestBase - for base in bases: - for attr_name in dir(base): - if attr_name not in d: - d[attr_name] = getattr(base, attr_name) - - for func_name, func in d.items(): - if func_name.startswith('test') and callable(func): - - setattr(cls, func_name, MoxMetaTestBase.CleanUpTest(cls, func)) - - @staticmethod - def CleanUpTest(cls, func): - """Adds Mox cleanup code to any MoxTestBase method. - - Always unsets stubs after a test. Will verify all mocks for tests that - otherwise pass. - - Args: - cls: MoxTestBase or subclass; the class whose method we are altering. - func: method; the method of the MoxTestBase test class we wish to alter. - - Returns: - The modified method. + As the mox unit testing class is being constructed (MoxTestBase or a + subclass), this metaclass will modify all test functions to call the + CleanUpMox method of the test class after they finish. This means that + unstubbing and verifying will happen for every test with no additional code, + and any failures will result in test failures as opposed to errors. """ - def new_method(self, *args, **kwargs): - mox_obj = getattr(self, 'mox', None) - stubout_obj = getattr(self, 'stubs', None) - cleanup_mox = False - cleanup_stubout = False - if mox_obj and isinstance(mox_obj, Mox): - cleanup_mox = True - if stubout_obj and isinstance(stubout_obj, stubout.StubOutForTesting): - cleanup_stubout = True - try: - func(self, *args, **kwargs) - finally: - if cleanup_mox: - mox_obj.UnsetStubs() - if cleanup_stubout: - stubout_obj.UnsetAll() - stubout_obj.SmartUnsetAll() - if cleanup_mox: - mox_obj.VerifyAll() - new_method.__name__ = func.__name__ - new_method.__doc__ = func.__doc__ - new_method.__module__ = func.__module__ - return new_method + + def __init__(cls, name, bases, d): + type.__init__(cls, name, bases, d) + + # also get all the attributes from the base classes to account + # for a case when test class is not the immediate child of MoxTestBase + for base in bases: + for attr_name in dir(base): + if attr_name not in d: + d[attr_name] = getattr(base, attr_name) + + for func_name, func in d.items(): + if func_name.startswith('test') and callable(func): + + setattr(cls, func_name, MoxMetaTestBase.CleanUpTest(cls, func)) + + @staticmethod + def CleanUpTest(cls, func): + """Adds Mox cleanup code to any MoxTestBase method. + + Always unsets stubs after a test. Will verify all mocks for tests that + otherwise pass. + + Args: + cls: MoxTestBase or subclass; the class whose method we are altering. + func: method; the method of the MoxTestBase test class we wish to alter. + + Returns: + The modified method. + """ + def new_method(self, *args, **kwargs): + mox_obj = getattr(self, 'mox', None) + stubout_obj = getattr(self, 'stubs', None) + cleanup_mox = False + cleanup_stubout = False + if mox_obj and isinstance(mox_obj, Mox): + cleanup_mox = True + if stubout_obj and isinstance(stubout_obj, stubout.StubOutForTesting): + cleanup_stubout = True + try: + func(self, *args, **kwargs) + finally: + if cleanup_mox: + mox_obj.UnsetStubs() + if cleanup_stubout: + stubout_obj.UnsetAll() + stubout_obj.SmartUnsetAll() + if cleanup_mox: + mox_obj.VerifyAll() + new_method.__name__ = func.__name__ + new_method.__doc__ = func.__doc__ + new_method.__module__ = func.__module__ + return new_method _MoxTestBase = MoxMetaTestBase('_MoxTestBase', (unittest.TestCase, ), {}) class MoxTestBase(_MoxTestBase): - """Convenience test class to make stubbing easier. + """Convenience test class to make stubbing easier. - Sets up a "mox" attribute which is an instance of Mox (any mox tests will - want this), and a "stubs" attribute that is an instance of StubOutForTesting - (needed at times). Also automatically unsets any stubs and verifies that all - mock methods have been called at the end of each test, eliminating - boilerplate code. - """ + Sets up a "mox" attribute which is an instance of Mox (any mox tests will + want this), and a "stubs" attribute that is an instance of StubOutForTesting + (needed at times). Also automatically unsets any stubs and verifies that all + mock methods have been called at the end of each test, eliminating + boilerplate code. + """ - def setUp(self): - super(MoxTestBase, self).setUp() - self.mox = Mox() - self.stubs = stubout.StubOutForTesting() + def setUp(self): + super(MoxTestBase, self).setUp() + self.mox = Mox() + self.stubs = stubout.StubOutForTesting() diff --git a/mox3/stubout.py b/mox3/stubout.py index f956c3b..2681e5d 100644 --- a/mox3/stubout.py +++ b/mox3/stubout.py @@ -20,126 +20,126 @@ import inspect class StubOutForTesting(object): - """Sample Usage: - You want os.path.exists() to always return true during testing. + """Sample Usage: + You want os.path.exists() to always return true during testing. - stubs = StubOutForTesting() - stubs.Set(os.path, 'exists', lambda x: 1) - ... - stubs.UnsetAll() + stubs = StubOutForTesting() + stubs.Set(os.path, 'exists', lambda x: 1) + ... + stubs.UnsetAll() - The above changes os.path.exists into a lambda that returns 1. Once - the ... part of the code finishes, the UnsetAll() looks up the old value - of os.path.exists and restores it. - - """ - def __init__(self): - self.cache = [] - self.stubs = [] - - def __del__(self): - self.SmartUnsetAll() - self.UnsetAll() - - def SmartSet(self, obj, attr_name, new_attr): - """Replace obj.attr_name with new_attr. This method is smart and works - at the module, class, and instance level while preserving proper - inheritance. It will not stub out C types however unless that has been - explicitly allowed by the type. - - This method supports the case where attr_name is a staticmethod or a - classmethod of obj. - - Notes: - - If obj is an instance, then it is its class that will actually be - stubbed. Note that the method Set() does not do that: if obj is - an instance, it (and not its class) will be stubbed. - - The stubbing is using the builtin getattr and setattr. So, the __get__ - and __set__ will be called when stubbing (TODO: A better idea would - probably be to manipulate obj.__dict__ instead of getattr() and - setattr()). - - Raises AttributeError if the attribute cannot be found. - """ - if (inspect.ismodule(obj) or - (not inspect.isclass(obj) and attr_name in obj.__dict__)): - orig_obj = obj - orig_attr = getattr(obj, attr_name) - - else: - if not inspect.isclass(obj): - mro = list(inspect.getmro(obj.__class__)) - else: - mro = list(inspect.getmro(obj)) - - mro.reverse() - - orig_attr = None - - for cls in mro: - try: - orig_obj = cls - orig_attr = getattr(obj, attr_name) - except AttributeError: - continue - - if orig_attr is None: - raise AttributeError("Attribute not found.") - - # Calling getattr() on a staticmethod transforms it to a 'normal' function. - # We need to ensure that we put it back as a staticmethod. - old_attribute = obj.__dict__.get(attr_name) - if old_attribute is not None and isinstance(old_attribute, staticmethod): - orig_attr = staticmethod(orig_attr) - - self.stubs.append((orig_obj, attr_name, orig_attr)) - setattr(orig_obj, attr_name, new_attr) - - def SmartUnsetAll(self): - """Reverses all the SmartSet() calls, restoring things to their original - definition. Its okay to call SmartUnsetAll() repeatedly, as later calls - have no effect if no SmartSet() calls have been made. + The above changes os.path.exists into a lambda that returns 1. Once + the ... part of the code finishes, the UnsetAll() looks up the old value + of os.path.exists and restores it. """ - self.stubs.reverse() + def __init__(self): + self.cache = [] + self.stubs = [] - for args in self.stubs: - setattr(*args) + def __del__(self): + self.SmartUnsetAll() + self.UnsetAll() - self.stubs = [] + def SmartSet(self, obj, attr_name, new_attr): + """Replace obj.attr_name with new_attr. This method is smart and works + at the module, class, and instance level while preserving proper + inheritance. It will not stub out C types however unless that has been + explicitly allowed by the type. - def Set(self, parent, child_name, new_child): - """Replace child_name's old definition with new_child, in the context - of the given parent. The parent could be a module when the child is a - function at module scope. Or the parent could be a class when a class' - method is being replaced. The named child is set to new_child, while - the prior definition is saved away for later, when UnsetAll() is called. + This method supports the case where attr_name is a staticmethod or a + classmethod of obj. - This method supports the case where child_name is a staticmethod or a - classmethod of parent. - """ - old_child = getattr(parent, child_name) + Notes: + - If obj is an instance, then it is its class that will actually be + stubbed. Note that the method Set() does not do that: if obj is + an instance, it (and not its class) will be stubbed. + - The stubbing is using the builtin getattr and setattr. So, the __get__ + and __set__ will be called when stubbing (TODO: A better idea would + probably be to manipulate obj.__dict__ instead of getattr() and + setattr()). - old_attribute = parent.__dict__.get(child_name) - if old_attribute is not None: - if isinstance(old_attribute, staticmethod): - old_child = staticmethod(old_child) - elif isinstance(old_attribute, classmethod): - old_child = classmethod(old_child.__func__) + Raises AttributeError if the attribute cannot be found. + """ + if (inspect.ismodule(obj) or + (not inspect.isclass(obj) and attr_name in obj.__dict__)): + orig_obj = obj + orig_attr = getattr(obj, attr_name) - self.cache.append((parent, old_child, child_name)) - setattr(parent, child_name, new_child) + else: + if not inspect.isclass(obj): + mro = list(inspect.getmro(obj.__class__)) + else: + mro = list(inspect.getmro(obj)) - def UnsetAll(self): - """Reverses all the Set() calls, restoring things to their original - definition. Its okay to call UnsetAll() repeatedly, as later calls have - no effect if no Set() calls have been made. + mro.reverse() - """ - # Undo calls to Set() in reverse order, in case Set() was called on the - # same arguments repeatedly (want the original call to be last one undone) - self.cache.reverse() + orig_attr = None - for (parent, old_child, child_name) in self.cache: - setattr(parent, child_name, old_child) - self.cache = [] + for cls in mro: + try: + orig_obj = cls + orig_attr = getattr(obj, attr_name) + except AttributeError: + continue + + if orig_attr is None: + raise AttributeError("Attribute not found.") + + # Calling getattr() on a staticmethod transforms it to a 'normal' function. + # We need to ensure that we put it back as a staticmethod. + old_attribute = obj.__dict__.get(attr_name) + if old_attribute is not None and isinstance(old_attribute, staticmethod): + orig_attr = staticmethod(orig_attr) + + self.stubs.append((orig_obj, attr_name, orig_attr)) + setattr(orig_obj, attr_name, new_attr) + + def SmartUnsetAll(self): + """Reverses all the SmartSet() calls, restoring things to their original + definition. Its okay to call SmartUnsetAll() repeatedly, as later calls + have no effect if no SmartSet() calls have been made. + + """ + self.stubs.reverse() + + for args in self.stubs: + setattr(*args) + + self.stubs = [] + + def Set(self, parent, child_name, new_child): + """Replace child_name's old definition with new_child, in the context + of the given parent. The parent could be a module when the child is a + function at module scope. Or the parent could be a class when a class' + method is being replaced. The named child is set to new_child, while + the prior definition is saved away for later, when UnsetAll() is called. + + This method supports the case where child_name is a staticmethod or a + classmethod of parent. + """ + old_child = getattr(parent, child_name) + + old_attribute = parent.__dict__.get(child_name) + if old_attribute is not None: + if isinstance(old_attribute, staticmethod): + old_child = staticmethod(old_child) + elif isinstance(old_attribute, classmethod): + old_child = classmethod(old_child.__func__) + + self.cache.append((parent, old_child, child_name)) + setattr(parent, child_name, new_child) + + def UnsetAll(self): + """Reverses all the Set() calls, restoring things to their original + definition. Its okay to call UnsetAll() repeatedly, as later calls have + no effect if no Set() calls have been made. + + """ + # Undo calls to Set() in reverse order, in case Set() was called on the + # same arguments repeatedly (want the original call to be last one undone) + self.cache.reverse() + + for (parent, old_child, child_name) in self.cache: + setattr(parent, child_name, old_child) + self.cache = [] diff --git a/mox3/tests/mox_helper.py b/mox3/tests/mox_helper.py index 4191ba6..67843a9 100644 --- a/mox3/tests/mox_helper.py +++ b/mox3/tests/mox_helper.py @@ -33,113 +33,113 @@ from mox3 import mox class ExampleMoxTestMixin(object): - """Mix-in class for mox test case class. + """Mix-in class for mox test case class. - It stubs out the same function as one of the test methods in - the example test case. Both tests must pass as meta class wraps - test methods in all base classes. - """ + It stubs out the same function as one of the test methods in + the example test case. Both tests must pass as meta class wraps + test methods in all base classes. + """ - def testStat(self): - self.mox.StubOutWithMock(os, 'stat') - os.stat(self.DIR_PATH) - self.mox.ReplayAll() - os.stat(self.DIR_PATH) + def testStat(self): + self.mox.StubOutWithMock(os, 'stat') + os.stat(self.DIR_PATH) + self.mox.ReplayAll() + os.stat(self.DIR_PATH) class ExampleMoxTest(mox.MoxTestBase, ExampleMoxTestMixin): - DIR_PATH = '/path/to/some/directory' + DIR_PATH = '/path/to/some/directory' - def testSuccess(self): - self.mox.StubOutWithMock(os, 'listdir') - os.listdir(self.DIR_PATH) - self.mox.ReplayAll() - os.listdir(self.DIR_PATH) + def testSuccess(self): + self.mox.StubOutWithMock(os, 'listdir') + os.listdir(self.DIR_PATH) + self.mox.ReplayAll() + os.listdir(self.DIR_PATH) - def testExpectedNotCalled(self): - self.mox.StubOutWithMock(os, 'listdir') - os.listdir(self.DIR_PATH) - self.mox.ReplayAll() + def testExpectedNotCalled(self): + self.mox.StubOutWithMock(os, 'listdir') + os.listdir(self.DIR_PATH) + self.mox.ReplayAll() - def testUnexpectedCall(self): - self.mox.StubOutWithMock(os, 'listdir') - os.listdir(self.DIR_PATH) - self.mox.ReplayAll() - os.listdir('/path/to/some/other/directory') - os.listdir(self.DIR_PATH) + def testUnexpectedCall(self): + self.mox.StubOutWithMock(os, 'listdir') + os.listdir(self.DIR_PATH) + self.mox.ReplayAll() + os.listdir('/path/to/some/other/directory') + os.listdir(self.DIR_PATH) - def testFailure(self): - self.assertTrue(False) + def testFailure(self): + self.assertTrue(False) - def testStatOther(self): - self.mox.StubOutWithMock(os, 'stat') - os.stat(self.DIR_PATH) - self.mox.ReplayAll() - os.stat(self.DIR_PATH) + def testStatOther(self): + self.mox.StubOutWithMock(os, 'stat') + os.stat(self.DIR_PATH) + self.mox.ReplayAll() + os.stat(self.DIR_PATH) - def testHasStubs(self): - listdir_list = [] + def testHasStubs(self): + listdir_list = [] - def MockListdir(directory): - listdir_list.append(directory) + def MockListdir(directory): + listdir_list.append(directory) - self.stubs.Set(os, 'listdir', MockListdir) - os.listdir(self.DIR_PATH) - self.assertEqual([self.DIR_PATH], listdir_list) + self.stubs.Set(os, 'listdir', MockListdir) + os.listdir(self.DIR_PATH) + self.assertEqual([self.DIR_PATH], listdir_list) class TestClassFromAnotherModule(object): - def __init__(self): - return None + def __init__(self): + return None - def Value(self): - return 'Not mock' + def Value(self): + return 'Not mock' class ChildClassFromAnotherModule(TestClassFromAnotherModule): - """A child class of TestClassFromAnotherModule. + """A child class of TestClassFromAnotherModule. - Used to test stubbing out unbound methods, where child classes - are eventually bound. - """ + Used to test stubbing out unbound methods, where child classes + are eventually bound. + """ - def __init__(self): - TestClassFromAnotherModule.__init__(self) + def __init__(self): + TestClassFromAnotherModule.__init__(self) class CallableClass(object): - def __init__(self, one, two, nine=None): - pass + def __init__(self, one, two, nine=None): + pass - def __call__(self, one): - return 'Not mock' + def __call__(self, one): + return 'Not mock' - def Value(self): - return 'Not mock' + def Value(self): + return 'Not mock' def MyTestFunction(one, two, nine=None): - pass + pass class ExampleClass(object): - def __init__(self, foo='bar'): - pass + def __init__(self, foo='bar'): + pass - def TestMethod(self, one, two, nine=None): - pass + def TestMethod(self, one, two, nine=None): + pass - def NamedParams(self, ignore, foo='bar', baz='qux'): - pass + def NamedParams(self, ignore, foo='bar', baz='qux'): + pass - def SpecialArgs(self, *args, **kwargs): - pass + def SpecialArgs(self, *args, **kwargs): + pass # This class is used to test stubbing out __init__ of a parent class. class ChildExampleClass(ExampleClass): - def __init__(self): - ExampleClass.__init__(self) + def __init__(self): + ExampleClass.__init__(self) diff --git a/mox3/tests/stubout_helper.py b/mox3/tests/stubout_helper.py index 24e15ef..233de89 100644 --- a/mox3/tests/stubout_helper.py +++ b/mox3/tests/stubout_helper.py @@ -18,4 +18,4 @@ def SampleFunction(): - raise Exception('I should never be called!') + raise Exception('I should never be called!') diff --git a/mox3/tests/test_mox.py b/mox3/tests/test_mox.py index a331f3d..29c04f2 100644 --- a/mox3/tests/test_mox.py +++ b/mox3/tests/test_mox.py @@ -30,2356 +30,2356 @@ OS_LISTDIR = mox_helper.os.listdir class ExpectedMethodCallsErrorTest(unittest.TestCase): - """Test creation and string conversion of ExpectedMethodCallsError.""" + """Test creation and string conversion of ExpectedMethodCallsError.""" - def testAtLeastOneMethod(self): - self.assertRaises(ValueError, mox.ExpectedMethodCallsError, []) + def testAtLeastOneMethod(self): + self.assertRaises(ValueError, mox.ExpectedMethodCallsError, []) - def testOneError(self): - method = mox.MockMethod("testMethod", [], False) - method(1, 2).AndReturn('output') - e = mox.ExpectedMethodCallsError([method]) - self.assertEqual( - "Verify: Expected methods never called:\n" - " 0. testMethod(1, 2) -> 'output'", - str(e)) + def testOneError(self): + method = mox.MockMethod("testMethod", [], False) + method(1, 2).AndReturn('output') + e = mox.ExpectedMethodCallsError([method]) + self.assertEqual( + "Verify: Expected methods never called:\n" + " 0. testMethod(1, 2) -> 'output'", + str(e)) - def testManyErrors(self): - method1 = mox.MockMethod("testMethod", [], False) - method1(1, 2).AndReturn('output') - method2 = mox.MockMethod("testMethod", [], False) - method2(a=1, b=2, c="only named") - method3 = mox.MockMethod("testMethod2", [], False) - method3().AndReturn(44) - method4 = mox.MockMethod("testMethod", [], False) - method4(1, 2).AndReturn('output') - e = mox.ExpectedMethodCallsError([method1, method2, method3, method4]) - self.assertEqual( - "Verify: Expected methods never called:\n" - " 0. testMethod(1, 2) -> 'output'\n" - " 1. testMethod(a=1, b=2, c='only named') -> None\n" - " 2. testMethod2() -> 44\n" - " 3. testMethod(1, 2) -> 'output'", - str(e)) + def testManyErrors(self): + method1 = mox.MockMethod("testMethod", [], False) + method1(1, 2).AndReturn('output') + method2 = mox.MockMethod("testMethod", [], False) + method2(a=1, b=2, c="only named") + method3 = mox.MockMethod("testMethod2", [], False) + method3().AndReturn(44) + method4 = mox.MockMethod("testMethod", [], False) + method4(1, 2).AndReturn('output') + e = mox.ExpectedMethodCallsError([method1, method2, method3, method4]) + self.assertEqual( + "Verify: Expected methods never called:\n" + " 0. testMethod(1, 2) -> 'output'\n" + " 1. testMethod(a=1, b=2, c='only named') -> None\n" + " 2. testMethod2() -> 44\n" + " 3. testMethod(1, 2) -> 'output'", + str(e)) class OrTest(unittest.TestCase): - """Test Or correctly chains Comparators.""" + """Test Or correctly chains Comparators.""" - def testValidOr(self): - """Or should be True if either Comparator returns True.""" - self.assertTrue(mox.Or(mox.IsA(dict), mox.IsA(str)) == {}) - self.assertTrue(mox.Or(mox.IsA(dict), mox.IsA(str)) == 'test') - self.assertTrue(mox.Or(mox.IsA(str), mox.IsA(str)) == 'test') + def testValidOr(self): + """Or should be True if either Comparator returns True.""" + self.assertTrue(mox.Or(mox.IsA(dict), mox.IsA(str)) == {}) + self.assertTrue(mox.Or(mox.IsA(dict), mox.IsA(str)) == 'test') + self.assertTrue(mox.Or(mox.IsA(str), mox.IsA(str)) == 'test') - def testInvalidOr(self): - """Or should be False if both Comparators return False.""" - self.assertFalse(mox.Or(mox.IsA(dict), mox.IsA(str)) == 0) + def testInvalidOr(self): + """Or should be False if both Comparators return False.""" + self.assertFalse(mox.Or(mox.IsA(dict), mox.IsA(str)) == 0) class AndTest(unittest.TestCase): - """Test And correctly chains Comparators.""" + """Test And correctly chains Comparators.""" - def testValidAnd(self): - """And should be True if both Comparators return True.""" - self.assertTrue(mox.And(mox.IsA(str), mox.IsA(str)) == '1') + def testValidAnd(self): + """And should be True if both Comparators return True.""" + self.assertTrue(mox.And(mox.IsA(str), mox.IsA(str)) == '1') - def testClauseOneFails(self): - """And should be False if the first Comparator returns False.""" + def testClauseOneFails(self): + """And should be False if the first Comparator returns False.""" - self.assertFalse(mox.And(mox.IsA(dict), mox.IsA(str)) == '1') + self.assertFalse(mox.And(mox.IsA(dict), mox.IsA(str)) == '1') - def testAdvancedUsage(self): - """And should work with other Comparators. + def testAdvancedUsage(self): + """And should work with other Comparators. - Note: this test is reliant on In and ContainsKeyValue. - """ - test_dict = {"mock": "obj", "testing": "isCOOL"} - self.assertTrue(mox.And(mox.In("testing"), - mox.ContainsKeyValue("mock", "obj")) == test_dict) + Note: this test is reliant on In and ContainsKeyValue. + """ + test_dict = {"mock": "obj", "testing": "isCOOL"} + self.assertTrue(mox.And(mox.In("testing"), + mox.ContainsKeyValue("mock", "obj")) == test_dict) - def testAdvancedUsageFails(self): - """Note: this test is reliant on In and ContainsKeyValue.""" - test_dict = {"mock": "obj", "testing": "isCOOL"} - self.assertFalse(mox.And(mox.In("NOTFOUND"), - mox.ContainsKeyValue("mock", "obj")) == test_dict) + def testAdvancedUsageFails(self): + """Note: this test is reliant on In and ContainsKeyValue.""" + test_dict = {"mock": "obj", "testing": "isCOOL"} + self.assertFalse(mox.And(mox.In("NOTFOUND"), + mox.ContainsKeyValue("mock", "obj")) == test_dict) class FuncTest(unittest.TestCase): - """Test Func correctly evaluates based upon true-false return.""" + """Test Func correctly evaluates based upon true-false return.""" - def testFuncTrueFalseEvaluation(self): - """Should return True if the validating function returns True.""" - equals_one = lambda x: x == 1 - always_none = lambda x: None + def testFuncTrueFalseEvaluation(self): + """Should return True if the validating function returns True.""" + equals_one = lambda x: x == 1 + always_none = lambda x: None - self.assertTrue(mox.Func(equals_one) == 1) - self.assertFalse(mox.Func(equals_one) == 0) + self.assertTrue(mox.Func(equals_one) == 1) + self.assertFalse(mox.Func(equals_one) == 0) - self.assertFalse(mox.Func(always_none) == 1) - self.assertFalse(mox.Func(always_none) == 0) - self.assertFalse(mox.Func(always_none) == None) + self.assertFalse(mox.Func(always_none) == 1) + self.assertFalse(mox.Func(always_none) == 0) + self.assertFalse(mox.Func(always_none) == None) - def testFuncExceptionPropagation(self): - """Exceptions within the validating function should propagate.""" - class TestException(Exception): - pass + def testFuncExceptionPropagation(self): + """Exceptions within the validating function should propagate.""" + class TestException(Exception): + pass - def raiseExceptionOnNotOne(value): - if value != 1: - raise TestException - else: - return True + def raiseExceptionOnNotOne(value): + if value != 1: + raise TestException + else: + return True - self.assertTrue(mox.Func(raiseExceptionOnNotOne) == 1) - self.assertRaises( - TestException, mox.Func(raiseExceptionOnNotOne).__eq__, 2) + self.assertTrue(mox.Func(raiseExceptionOnNotOne) == 1) + self.assertRaises( + TestException, mox.Func(raiseExceptionOnNotOne).__eq__, 2) class SameElementsAsTest(unittest.TestCase): - """Test SameElementsAs correctly identifies sequences with same elements.""" + """Test SameElementsAs correctly identifies sequences with same elements.""" - def testSortedLists(self): - """Should return True if two lists are exactly equal.""" - self.assertTrue(mox.SameElementsAs([1, 2.0, 'c']) == [1, 2.0, 'c']) + def testSortedLists(self): + """Should return True if two lists are exactly equal.""" + self.assertTrue(mox.SameElementsAs([1, 2.0, 'c']) == [1, 2.0, 'c']) - def testUnsortedLists(self): - """Should return True if two lists are unequal but have same elements.""" - self.assertTrue(mox.SameElementsAs([1, 2.0, 'c']) == [2.0, 'c', 1]) + def testUnsortedLists(self): + """Should return True if two lists are unequal but have same elements.""" + self.assertTrue(mox.SameElementsAs([1, 2.0, 'c']) == [2.0, 'c', 1]) - def testUnhashableLists(self): - """Should return True if two lists have the same unhashable elements.""" - self.assertTrue(mox.SameElementsAs([{'a': 1}, {2: 'b'}]) == - [{2: 'b'}, {'a': 1}]) + def testUnhashableLists(self): + """Should return True if two lists have the same unhashable elements.""" + self.assertTrue(mox.SameElementsAs([{'a': 1}, {2: 'b'}]) == + [{2: 'b'}, {'a': 1}]) - def testEmptyLists(self): - """Should return True for two empty lists.""" - self.assertTrue(mox.SameElementsAs([]) == []) + def testEmptyLists(self): + """Should return True for two empty lists.""" + self.assertTrue(mox.SameElementsAs([]) == []) - def testUnequalLists(self): - """Should return False if the lists are not equal.""" - self.assertFalse(mox.SameElementsAs([1, 2.0, 'c']) == [2.0, 'c']) + def testUnequalLists(self): + """Should return False if the lists are not equal.""" + self.assertFalse(mox.SameElementsAs([1, 2.0, 'c']) == [2.0, 'c']) - def testUnequalUnhashableLists(self): - """Should return False if two lists with unhashable items are unequal.""" - self.assertFalse(mox.SameElementsAs([{'a': 1}, {2: 'b'}]) == [{2: 'b'}]) + def testUnequalUnhashableLists(self): + """Should return False if two lists with unhashable items are unequal.""" + self.assertFalse(mox.SameElementsAs([{'a': 1}, {2: 'b'}]) == [{2: 'b'}]) - def testActualIsNotASequence(self): - """Should return False if the actual object is not a sequence.""" - self.assertFalse(mox.SameElementsAs([1]) == object()) + def testActualIsNotASequence(self): + """Should return False if the actual object is not a sequence.""" + self.assertFalse(mox.SameElementsAs([1]) == object()) - def testOneUnhashableObjectInActual(self): - """Store the entire iterator for a correct comparison. + def testOneUnhashableObjectInActual(self): + """Store the entire iterator for a correct comparison. - In a previous version of SameElementsAs, iteration stopped when an - unhashable object was encountered and then was restarted, so the actual - list appeared smaller than it was. - """ - self.assertFalse(mox.SameElementsAs([1, 2]) == iter([{}, 1, 2])) + In a previous version of SameElementsAs, iteration stopped when an + unhashable object was encountered and then was restarted, so the actual + list appeared smaller than it was. + """ + self.assertFalse(mox.SameElementsAs([1, 2]) == iter([{}, 1, 2])) class ContainsKeyValueTest(unittest.TestCase): - """Test ContainsKeyValue correctly identifies key/value pairs in a dict. - """ + """Test ContainsKeyValue correctly identifies key/value pairs in a dict. + """ - def testValidPair(self): - """Should return True if the key value is in the dict.""" - self.assertTrue(mox.ContainsKeyValue("key", 1) == {"key": 1}) + def testValidPair(self): + """Should return True if the key value is in the dict.""" + self.assertTrue(mox.ContainsKeyValue("key", 1) == {"key": 1}) - def testInvalidValue(self): - """Should return False if the value is not correct.""" - self.assertFalse(mox.ContainsKeyValue("key", 1) == {"key": 2}) + def testInvalidValue(self): + """Should return False if the value is not correct.""" + self.assertFalse(mox.ContainsKeyValue("key", 1) == {"key": 2}) - def testInvalidKey(self): - """Should return False if they key is not in the dict.""" - self.assertFalse(mox.ContainsKeyValue("qux", 1) == {"key": 2}) + def testInvalidKey(self): + """Should return False if they key is not in the dict.""" + self.assertFalse(mox.ContainsKeyValue("qux", 1) == {"key": 2}) class ContainsAttributeValueTest(unittest.TestCase): - """Test ContainsAttributeValue correctly identifies properties in an object. - """ + """Test ContainsAttributeValue correctly identifies properties in an object. + """ - def setUp(self): - """Create an object to test with.""" + def setUp(self): + """Create an object to test with.""" - class TestObject(object): - key = 1 + class TestObject(object): + key = 1 - self.test_object = TestObject() + self.test_object = TestObject() - def testValidPair(self): - """Should return True if the object has the key attribute that matches.""" - self.assertTrue(mox.ContainsAttributeValue("key", 1) == self.test_object) + def testValidPair(self): + """Should return True if the object has the key attribute that matches.""" + self.assertTrue(mox.ContainsAttributeValue("key", 1) == self.test_object) - def testInvalidValue(self): - """Should return False if the value is not correct.""" - self.assertFalse(mox.ContainsKeyValue("key", 2) == self.test_object) + def testInvalidValue(self): + """Should return False if the value is not correct.""" + self.assertFalse(mox.ContainsKeyValue("key", 2) == self.test_object) - def testInvalidKey(self): - """Should return False if they the object doesn't have the property.""" - self.assertFalse(mox.ContainsKeyValue("qux", 1) == self.test_object) + def testInvalidKey(self): + """Should return False if they the object doesn't have the property.""" + self.assertFalse(mox.ContainsKeyValue("qux", 1) == self.test_object) class InTest(unittest.TestCase): - """Test In correctly identifies a key in a list/dict""" + """Test In correctly identifies a key in a list/dict""" - def testItemInList(self): - """Should return True if the item is in the list.""" - self.assertTrue(mox.In(1) == [1, 2, 3]) + def testItemInList(self): + """Should return True if the item is in the list.""" + self.assertTrue(mox.In(1) == [1, 2, 3]) - def testKeyInDict(self): - """Should return True if the item is a key in a dict.""" - self.assertTrue(mox.In("test") == {"test": "module"}) + def testKeyInDict(self): + """Should return True if the item is a key in a dict.""" + self.assertTrue(mox.In("test") == {"test": "module"}) - def testItemInTuple(self): - """Should return True if the item is in the list.""" - self.assertTrue(mox.In(1) == (1, 2, 3)) + def testItemInTuple(self): + """Should return True if the item is in the list.""" + self.assertTrue(mox.In(1) == (1, 2, 3)) - def testTupleInTupleOfTuples(self): - self.assertTrue(mox.In((1, 2, 3)) == ((1, 2, 3), (1, 2))) + def testTupleInTupleOfTuples(self): + self.assertTrue(mox.In((1, 2, 3)) == ((1, 2, 3), (1, 2))) - def testItemNotInList(self): - self.assertFalse(mox.In(1) == [2, 3]) + def testItemNotInList(self): + self.assertFalse(mox.In(1) == [2, 3]) - def testTupleNotInTupleOfTuples(self): - self.assertFalse(mox.In((1, 2)) == ((1, 2, 3), (4, 5))) + def testTupleNotInTupleOfTuples(self): + self.assertFalse(mox.In((1, 2)) == ((1, 2, 3), (4, 5))) class NotTest(unittest.TestCase): - """Test Not correctly identifies False predicates.""" + """Test Not correctly identifies False predicates.""" - def testItemInList(self): - """Should return True if the item is NOT in the list.""" - self.assertTrue(mox.Not(mox.In(42)) == [1, 2, 3]) + def testItemInList(self): + """Should return True if the item is NOT in the list.""" + self.assertTrue(mox.Not(mox.In(42)) == [1, 2, 3]) - def testKeyInDict(self): - """Should return True if the item is NOT a key in a dict.""" - self.assertTrue(mox.Not(mox.In("foo")) == {"key": 42}) + def testKeyInDict(self): + """Should return True if the item is NOT a key in a dict.""" + self.assertTrue(mox.Not(mox.In("foo")) == {"key": 42}) - def testInvalidKeyWithNot(self): - """Should return False if they key is NOT in the dict.""" - self.assertTrue(mox.Not(mox.ContainsKeyValue("qux", 1)) == {"key": 2}) + def testInvalidKeyWithNot(self): + """Should return False if they key is NOT in the dict.""" + self.assertTrue(mox.Not(mox.ContainsKeyValue("qux", 1)) == {"key": 2}) class StrContainsTest(unittest.TestCase): - """Test StrContains correctly checks for substring occurrence of a parameter. - """ + """Test StrContains correctly checks for substring occurrence of a parameter. + """ - def testValidSubstringAtStart(self): - """Should return True if the substring is at the start of the string.""" - self.assertTrue(mox.StrContains("hello") == "hello world") + def testValidSubstringAtStart(self): + """Should return True if the substring is at the start of the string.""" + self.assertTrue(mox.StrContains("hello") == "hello world") - def testValidSubstringInMiddle(self): - """Should return True if the substring is in the middle of the string.""" - self.assertTrue(mox.StrContains("lo wo") == "hello world") + def testValidSubstringInMiddle(self): + """Should return True if the substring is in the middle of the string.""" + self.assertTrue(mox.StrContains("lo wo") == "hello world") - def testValidSubstringAtEnd(self): - """Should return True if the substring is at the end of the string.""" - self.assertTrue(mox.StrContains("ld") == "hello world") + def testValidSubstringAtEnd(self): + """Should return True if the substring is at the end of the string.""" + self.assertTrue(mox.StrContains("ld") == "hello world") - def testInvaildSubstring(self): - """Should return False if the substring is not in the string.""" - self.assertFalse(mox.StrContains("AAA") == "hello world") + def testInvaildSubstring(self): + """Should return False if the substring is not in the string.""" + self.assertFalse(mox.StrContains("AAA") == "hello world") - def testMultipleMatches(self): - """Should return True if there are multiple occurances of substring.""" - self.assertTrue(mox.StrContains("abc") == "ababcabcabcababc") + def testMultipleMatches(self): + """Should return True if there are multiple occurances of substring.""" + self.assertTrue(mox.StrContains("abc") == "ababcabcabcababc") class RegexTest(unittest.TestCase): - """Test Regex correctly matches regular expressions.""" + """Test Regex correctly matches regular expressions.""" - def testIdentifyBadSyntaxDuringInit(self): - """The user should know immediately if a regex has bad syntax.""" - self.assertRaises(re.error, mox.Regex, '(a|b') + def testIdentifyBadSyntaxDuringInit(self): + """The user should know immediately if a regex has bad syntax.""" + self.assertRaises(re.error, mox.Regex, '(a|b') - def testPatternInMiddle(self): - """Should return True if the pattern matches at the middle of the string. + def testPatternInMiddle(self): + """Should return True if the pattern matches at the middle of the string. - This ensures that re.search is used (instead of re.find). - """ - self.assertTrue(mox.Regex(r"a\s+b") == "x y z a b c") + This ensures that re.search is used (instead of re.find). + """ + self.assertTrue(mox.Regex(r"a\s+b") == "x y z a b c") - def testNonMatchPattern(self): - """Should return False if the pattern does not match the string.""" - self.assertFalse(mox.Regex(r"a\s+b") == "x y z") + def testNonMatchPattern(self): + """Should return False if the pattern does not match the string.""" + self.assertFalse(mox.Regex(r"a\s+b") == "x y z") - def testFlagsPassedCorrectly(self): - """Should return True as we pass IGNORECASE flag.""" - self.assertTrue(mox.Regex(r"A", re.IGNORECASE) == "a") + def testFlagsPassedCorrectly(self): + """Should return True as we pass IGNORECASE flag.""" + self.assertTrue(mox.Regex(r"A", re.IGNORECASE) == "a") - def testReprWithoutFlags(self): - """repr should return the regular expression pattern.""" - self.assertTrue( - repr(mox.Regex(r"a\s+b")) == "") + def testReprWithoutFlags(self): + """repr should return the regular expression pattern.""" + self.assertTrue( + repr(mox.Regex(r"a\s+b")) == "") - def testReprWithFlags(self): - """repr should return the regular expression pattern and flags.""" - self.assertTrue(repr(mox.Regex(r"a\s+b", flags=4)) == - "") + def testReprWithFlags(self): + """repr should return the regular expression pattern and flags.""" + self.assertTrue(repr(mox.Regex(r"a\s+b", flags=4)) == + "") class IsTest(unittest.TestCase): - """Verify Is correctly checks equality based upon identity, not value""" + """Verify Is correctly checks equality based upon identity, not value""" - class AlwaysComparesTrue(object): - def __eq__(self, other): - return True + class AlwaysComparesTrue(object): + def __eq__(self, other): + return True - def __cmp__(self, other): - return 0 + def __cmp__(self, other): + return 0 - def __ne__(self, other): - return False + def __ne__(self, other): + return False - def testEqualityValid(self): - o1 = self.AlwaysComparesTrue() - self.assertTrue(mox.Is(o1), o1) + def testEqualityValid(self): + o1 = self.AlwaysComparesTrue() + self.assertTrue(mox.Is(o1), o1) - def testEqualityInvalid(self): - o1 = self.AlwaysComparesTrue() - o2 = self.AlwaysComparesTrue() - self.assertTrue(o1 == o2) - # but... - self.assertFalse(mox.Is(o1) == o2) + def testEqualityInvalid(self): + o1 = self.AlwaysComparesTrue() + o2 = self.AlwaysComparesTrue() + self.assertTrue(o1 == o2) + # but... + self.assertFalse(mox.Is(o1) == o2) - def testInequalityValid(self): - o1 = self.AlwaysComparesTrue() - o2 = self.AlwaysComparesTrue() - self.assertTrue(mox.Is(o1) != o2) + def testInequalityValid(self): + o1 = self.AlwaysComparesTrue() + o2 = self.AlwaysComparesTrue() + self.assertTrue(mox.Is(o1) != o2) - def testInequalityInvalid(self): - o1 = self.AlwaysComparesTrue() - self.assertFalse(mox.Is(o1) != o1) + def testInequalityInvalid(self): + o1 = self.AlwaysComparesTrue() + self.assertFalse(mox.Is(o1) != o1) - def testEqualityInListValid(self): - o1 = self.AlwaysComparesTrue() - o2 = self.AlwaysComparesTrue() - isa_list = [mox.Is(o1), mox.Is(o2)] - str_list = [o1, o2] - self.assertTrue(isa_list == str_list) + def testEqualityInListValid(self): + o1 = self.AlwaysComparesTrue() + o2 = self.AlwaysComparesTrue() + isa_list = [mox.Is(o1), mox.Is(o2)] + str_list = [o1, o2] + self.assertTrue(isa_list == str_list) - def testEquailtyInListInvalid(self): - o1 = self.AlwaysComparesTrue() - o2 = self.AlwaysComparesTrue() - isa_list = [mox.Is(o1), mox.Is(o2)] - mixed_list = [o2, o1] - self.assertFalse(isa_list == mixed_list) + def testEquailtyInListInvalid(self): + o1 = self.AlwaysComparesTrue() + o2 = self.AlwaysComparesTrue() + isa_list = [mox.Is(o1), mox.Is(o2)] + mixed_list = [o2, o1] + self.assertFalse(isa_list == mixed_list) class IsATest(unittest.TestCase): - """Verify IsA correctly checks equality based upon class type, not value.""" + """Verify IsA correctly checks equality based upon class type, not value.""" - def testEqualityValid(self): - """Verify that == correctly identifies objects of the same type.""" - self.assertTrue(mox.IsA(str) == 'test') + def testEqualityValid(self): + """Verify that == correctly identifies objects of the same type.""" + self.assertTrue(mox.IsA(str) == 'test') - def testEqualityInvalid(self): - """Verify that == correctly identifies objects of different types.""" - self.assertFalse(mox.IsA(str) == 10) + def testEqualityInvalid(self): + """Verify that == correctly identifies objects of different types.""" + self.assertFalse(mox.IsA(str) == 10) - def testInequalityValid(self): - """Verify that != identifies objects of different type.""" - self.assertTrue(mox.IsA(str) != 10) + def testInequalityValid(self): + """Verify that != identifies objects of different type.""" + self.assertTrue(mox.IsA(str) != 10) - def testInequalityInvalid(self): - """Verify that != correctly identifies objects of the same type.""" - self.assertFalse(mox.IsA(str) != "test") + def testInequalityInvalid(self): + """Verify that != correctly identifies objects of the same type.""" + self.assertFalse(mox.IsA(str) != "test") - def testEqualityInListValid(self): - """Verify list contents are properly compared.""" - isa_list = [mox.IsA(str), mox.IsA(str)] - str_list = ["abc", "def"] - self.assertTrue(isa_list == str_list) + def testEqualityInListValid(self): + """Verify list contents are properly compared.""" + isa_list = [mox.IsA(str), mox.IsA(str)] + str_list = ["abc", "def"] + self.assertTrue(isa_list == str_list) - def testEquailtyInListInvalid(self): - """Verify list contents are properly compared.""" - isa_list = [mox.IsA(str), mox.IsA(str)] - mixed_list = ["abc", 123] - self.assertFalse(isa_list == mixed_list) + def testEquailtyInListInvalid(self): + """Verify list contents are properly compared.""" + isa_list = [mox.IsA(str), mox.IsA(str)] + mixed_list = ["abc", 123] + self.assertFalse(isa_list == mixed_list) - def testSpecialTypes(self): - """Verify that IsA can handle objects like io.StringIO.""" - isA = mox.IsA(io.StringIO()) - stringIO = io.StringIO() - self.assertTrue(isA == stringIO) + def testSpecialTypes(self): + """Verify that IsA can handle objects like io.StringIO.""" + isA = mox.IsA(io.StringIO()) + stringIO = io.StringIO() + self.assertTrue(isA == stringIO) class IsAlmostTest(unittest.TestCase): - """Verify IsAlmost correctly checks equality of floating point numbers.""" + """Verify IsAlmost correctly checks equality of floating point numbers.""" - def testEqualityValid(self): - """Verify that == correctly identifies nearly equivalent floats.""" - self.assertEqual(mox.IsAlmost(1.8999999999), 1.9) + def testEqualityValid(self): + """Verify that == correctly identifies nearly equivalent floats.""" + self.assertEqual(mox.IsAlmost(1.8999999999), 1.9) - def testEqualityInvalid(self): - """Verify that == correctly identifies non-equivalent floats.""" - self.assertNotEqual(mox.IsAlmost(1.899), 1.9) + def testEqualityInvalid(self): + """Verify that == correctly identifies non-equivalent floats.""" + self.assertNotEqual(mox.IsAlmost(1.899), 1.9) - def testEqualityWithPlaces(self): - """Verify that specifying places has the desired effect.""" - self.assertNotEqual(mox.IsAlmost(1.899), 1.9) - self.assertEqual(mox.IsAlmost(1.899, places=2), 1.9) + def testEqualityWithPlaces(self): + """Verify that specifying places has the desired effect.""" + self.assertNotEqual(mox.IsAlmost(1.899), 1.9) + self.assertEqual(mox.IsAlmost(1.899, places=2), 1.9) - def testNonNumericTypes(self): - """Verify that IsAlmost handles non-numeric types properly.""" + def testNonNumericTypes(self): + """Verify that IsAlmost handles non-numeric types properly.""" - self.assertNotEqual(mox.IsAlmost(1.8999999999), '1.9') - self.assertNotEqual(mox.IsAlmost('1.8999999999'), 1.9) - self.assertNotEqual(mox.IsAlmost('1.8999999999'), '1.9') + self.assertNotEqual(mox.IsAlmost(1.8999999999), '1.9') + self.assertNotEqual(mox.IsAlmost('1.8999999999'), 1.9) + self.assertNotEqual(mox.IsAlmost('1.8999999999'), '1.9') class ValueRememberTest(unittest.TestCase): - """Verify comparing argument against remembered value.""" + """Verify comparing argument against remembered value.""" - def testValueEquals(self): - """Verify that value will compare to stored value.""" - value = mox.Value() - value.store_value('hello world') - self.assertEqual(value, 'hello world') + def testValueEquals(self): + """Verify that value will compare to stored value.""" + value = mox.Value() + value.store_value('hello world') + self.assertEqual(value, 'hello world') - def testNoValue(self): - """Verify that uninitialized value does not compare to "empty" values.""" - value = mox.Value() - self.assertNotEqual(value, None) - self.assertNotEqual(value, False) - self.assertNotEqual(value, 0) - self.assertNotEqual(value, '') - self.assertNotEqual(value, ()) - self.assertNotEqual(value, []) - self.assertNotEqual(value, {}) - self.assertNotEqual(value, object()) - self.assertNotEqual(value, set()) + def testNoValue(self): + """Verify that uninitialized value does not compare to "empty" values.""" + value = mox.Value() + self.assertNotEqual(value, None) + self.assertNotEqual(value, False) + self.assertNotEqual(value, 0) + self.assertNotEqual(value, '') + self.assertNotEqual(value, ()) + self.assertNotEqual(value, []) + self.assertNotEqual(value, {}) + self.assertNotEqual(value, object()) + self.assertNotEqual(value, set()) - def testRememberValue(self): - """Verify that comparing against remember will store argument.""" - value = mox.Value() - remember = mox.Remember(value) - self.assertNotEqual(value, 'hello world') # value not yet stored. - self.assertEqual(remember, 'hello world') # store value here. - self.assertEqual(value, 'hello world') # compare against stored value. + def testRememberValue(self): + """Verify that comparing against remember will store argument.""" + value = mox.Value() + remember = mox.Remember(value) + self.assertNotEqual(value, 'hello world') # value not yet stored. + self.assertEqual(remember, 'hello world') # store value here. + self.assertEqual(value, 'hello world') # compare against stored value. class MockMethodTest(unittest.TestCase): - """Test class to verify that the MockMethod class is working correctly.""" + """Test class to verify that the MockMethod class is working correctly.""" - def setUp(self): - self.expected_method = mox.MockMethod( - "testMethod", [], False)(['original']) - self.mock_method = mox.MockMethod("testMethod", [self.expected_method], - True) + def setUp(self): + self.expected_method = mox.MockMethod( + "testMethod", [], False)(['original']) + self.mock_method = mox.MockMethod("testMethod", [self.expected_method], + True) - def testNameAttribute(self): - """Should provide a __name__ attribute.""" - self.assertEqual('testMethod', self.mock_method.__name__) + def testNameAttribute(self): + """Should provide a __name__ attribute.""" + self.assertEqual('testMethod', self.mock_method.__name__) - def testAndReturnNoneByDefault(self): - """Should return None by default.""" - return_value = self.mock_method(['original']) - self.assertTrue(return_value == None) + def testAndReturnNoneByDefault(self): + """Should return None by default.""" + return_value = self.mock_method(['original']) + self.assertTrue(return_value == None) - def testAndReturnValue(self): - """Should return a specificed return value.""" - expected_return_value = "test" - self.expected_method.AndReturn(expected_return_value) - return_value = self.mock_method(['original']) - self.assertTrue(return_value == expected_return_value) + def testAndReturnValue(self): + """Should return a specificed return value.""" + expected_return_value = "test" + self.expected_method.AndReturn(expected_return_value) + return_value = self.mock_method(['original']) + self.assertTrue(return_value == expected_return_value) - def testAndRaiseException(self): - """Should raise a specified exception.""" - expected_exception = Exception('test exception') - self.expected_method.AndRaise(expected_exception) - self.assertRaises(Exception, self.mock_method) + def testAndRaiseException(self): + """Should raise a specified exception.""" + expected_exception = Exception('test exception') + self.expected_method.AndRaise(expected_exception) + self.assertRaises(Exception, self.mock_method) - def testWithSideEffects(self): - """Should call state modifier.""" - local_list = ['original'] + def testWithSideEffects(self): + """Should call state modifier.""" + local_list = ['original'] - def modifier(mutable_list): - self.assertTrue(local_list is mutable_list) - mutable_list[0] = 'mutation' + def modifier(mutable_list): + self.assertTrue(local_list is mutable_list) + mutable_list[0] = 'mutation' - self.expected_method.WithSideEffects(modifier).AndReturn(1) - self.mock_method(local_list) - self.assertEqual('mutation', local_list[0]) + self.expected_method.WithSideEffects(modifier).AndReturn(1) + self.mock_method(local_list) + self.assertEqual('mutation', local_list[0]) - def testWithReturningSideEffects(self): - """Should call state modifier and propagate its return value.""" - local_list = ['original'] - expected_return = 'expected_return' + def testWithReturningSideEffects(self): + """Should call state modifier and propagate its return value.""" + local_list = ['original'] + expected_return = 'expected_return' - def modifier_with_return(mutable_list): - self.assertTrue(local_list is mutable_list) - mutable_list[0] = 'mutation' - return expected_return + def modifier_with_return(mutable_list): + self.assertTrue(local_list is mutable_list) + mutable_list[0] = 'mutation' + return expected_return - self.expected_method.WithSideEffects(modifier_with_return) - actual_return = self.mock_method(local_list) - self.assertEqual('mutation', local_list[0]) - self.assertEqual(expected_return, actual_return) + self.expected_method.WithSideEffects(modifier_with_return) + actual_return = self.mock_method(local_list) + self.assertEqual('mutation', local_list[0]) + self.assertEqual(expected_return, actual_return) - def testWithReturningSideEffectsWithAndReturn(self): - """Should call state modifier and ignore its return value.""" - local_list = ['original'] - expected_return = 'expected_return' - unexpected_return = 'unexpected_return' + def testWithReturningSideEffectsWithAndReturn(self): + """Should call state modifier and ignore its return value.""" + local_list = ['original'] + expected_return = 'expected_return' + unexpected_return = 'unexpected_return' - def modifier_with_return(mutable_list): - self.assertTrue(local_list is mutable_list) - mutable_list[0] = 'mutation' - return unexpected_return + def modifier_with_return(mutable_list): + self.assertTrue(local_list is mutable_list) + mutable_list[0] = 'mutation' + return unexpected_return - self.expected_method.WithSideEffects(modifier_with_return).AndReturn( - expected_return) - actual_return = self.mock_method(local_list) - self.assertEqual('mutation', local_list[0]) - self.assertEqual(expected_return, actual_return) + self.expected_method.WithSideEffects(modifier_with_return).AndReturn( + expected_return) + actual_return = self.mock_method(local_list) + self.assertEqual('mutation', local_list[0]) + self.assertEqual(expected_return, actual_return) - def testEqualityNoParamsEqual(self): - """Methods with the same name and without params should be equal.""" - expected_method = mox.MockMethod("testMethod", [], False) - self.assertEqual(self.mock_method, expected_method) + def testEqualityNoParamsEqual(self): + """Methods with the same name and without params should be equal.""" + expected_method = mox.MockMethod("testMethod", [], False) + self.assertEqual(self.mock_method, expected_method) - def testEqualityNoParamsNotEqual(self): - """Methods with different names and without params should not be equal.""" - expected_method = mox.MockMethod("otherMethod", [], False) - self.assertNotEqual(self.mock_method, expected_method) + def testEqualityNoParamsNotEqual(self): + """Methods with different names and without params should not be equal.""" + expected_method = mox.MockMethod("otherMethod", [], False) + self.assertNotEqual(self.mock_method, expected_method) - def testEqualityParamsEqual(self): - """Methods with the same name and parameters should be equal.""" - params = [1, 2, 3] - expected_method = mox.MockMethod("testMethod", [], False) - expected_method._params = params + def testEqualityParamsEqual(self): + """Methods with the same name and parameters should be equal.""" + params = [1, 2, 3] + expected_method = mox.MockMethod("testMethod", [], False) + expected_method._params = params - self.mock_method._params = params - self.assertEqual(self.mock_method, expected_method) + self.mock_method._params = params + self.assertEqual(self.mock_method, expected_method) - def testEqualityParamsNotEqual(self): - """Methods with the same name and different params should not be equal.""" - expected_method = mox.MockMethod("testMethod", [], False) - expected_method._params = [1, 2, 3] + def testEqualityParamsNotEqual(self): + """Methods with the same name and different params should not be equal.""" + expected_method = mox.MockMethod("testMethod", [], False) + expected_method._params = [1, 2, 3] - self.mock_method._params = ['a', 'b', 'c'] - self.assertNotEqual(self.mock_method, expected_method) + self.mock_method._params = ['a', 'b', 'c'] + self.assertNotEqual(self.mock_method, expected_method) - def testEqualityNamedParamsEqual(self): - """Methods with the same name and same named params should be equal.""" - named_params = {"input1": "test", "input2": "params"} - expected_method = mox.MockMethod("testMethod", [], False) - expected_method._named_params = named_params + def testEqualityNamedParamsEqual(self): + """Methods with the same name and same named params should be equal.""" + named_params = {"input1": "test", "input2": "params"} + expected_method = mox.MockMethod("testMethod", [], False) + expected_method._named_params = named_params - self.mock_method._named_params = named_params - self.assertEqual(self.mock_method, expected_method) + self.mock_method._named_params = named_params + self.assertEqual(self.mock_method, expected_method) - def testEqualityNamedParamsNotEqual(self): - """Methods with the same name and diffnamed params should not be equal.""" - expected_method = mox.MockMethod("testMethod", [], False) - expected_method._named_params = {"input1": "test", "input2": "params"} + def testEqualityNamedParamsNotEqual(self): + """Methods with the same name and diffnamed params should not be equal.""" + expected_method = mox.MockMethod("testMethod", [], False) + expected_method._named_params = {"input1": "test", "input2": "params"} - self.mock_method._named_params = {"input1": "test2", "input2": "params2"} - self.assertNotEqual(self.mock_method, expected_method) + self.mock_method._named_params = {"input1": "test2", "input2": "params2"} + self.assertNotEqual(self.mock_method, expected_method) - def testEqualityWrongType(self): - """Method should not be equal to an object of a different type.""" - self.assertNotEqual(self.mock_method, "string?") + def testEqualityWrongType(self): + """Method should not be equal to an object of a different type.""" + self.assertNotEqual(self.mock_method, "string?") - def testObjectEquality(self): - """Equality of objects should work without a Comparator""" - instA = TestClass() - instB = TestClass() + def testObjectEquality(self): + """Equality of objects should work without a Comparator""" + instA = TestClass() + instB = TestClass() - params = [instA, ] - expected_method = mox.MockMethod("testMethod", [], False) - expected_method._params = params + params = [instA, ] + expected_method = mox.MockMethod("testMethod", [], False) + expected_method._params = params - self.mock_method._params = [instB, ] - self.assertEqual(self.mock_method, expected_method) + self.mock_method._params = [instB, ] + self.assertEqual(self.mock_method, expected_method) - def testStrConversion(self): - method = mox.MockMethod("f", [], False) - method(1, 2, "st", n1=8, n2="st2") - self.assertEqual(str(method), ("f(1, 2, 'st', n1=8, n2='st2') -> None")) + def testStrConversion(self): + method = mox.MockMethod("f", [], False) + method(1, 2, "st", n1=8, n2="st2") + self.assertEqual(str(method), ("f(1, 2, 'st', n1=8, n2='st2') -> None")) - method = mox.MockMethod("testMethod", [], False) - method(1, 2, "only positional") - self.assertEqual(str(method), - "testMethod(1, 2, 'only positional') -> None") + method = mox.MockMethod("testMethod", [], False) + method(1, 2, "only positional") + self.assertEqual(str(method), + "testMethod(1, 2, 'only positional') -> None") - method = mox.MockMethod("testMethod", [], False) - method(a=1, b=2, c="only named") - self.assertEqual(str(method), - "testMethod(a=1, b=2, c='only named') -> None") + method = mox.MockMethod("testMethod", [], False) + method(a=1, b=2, c="only named") + self.assertEqual(str(method), + "testMethod(a=1, b=2, c='only named') -> None") - method = mox.MockMethod("testMethod", [], False) - method() - self.assertEqual(str(method), "testMethod() -> None") + method = mox.MockMethod("testMethod", [], False) + method() + self.assertEqual(str(method), "testMethod() -> None") - method = mox.MockMethod("testMethod", [], False) - method(x="only 1 parameter") - self.assertEqual(str(method), "testMethod(x='only 1 parameter') -> None") + method = mox.MockMethod("testMethod", [], False) + method(x="only 1 parameter") + self.assertEqual(str(method), "testMethod(x='only 1 parameter') -> None") - method = mox.MockMethod("testMethod", [], False) - method().AndReturn('return_value') - self.assertEqual(str(method), "testMethod() -> 'return_value'") + method = mox.MockMethod("testMethod", [], False) + method().AndReturn('return_value') + self.assertEqual(str(method), "testMethod() -> 'return_value'") - method = mox.MockMethod("testMethod", [], False) - method().AndReturn(('a', {1: 2})) - self.assertEqual(str(method), "testMethod() -> ('a', {1: 2})") + method = mox.MockMethod("testMethod", [], False) + method().AndReturn(('a', {1: 2})) + self.assertEqual(str(method), "testMethod() -> ('a', {1: 2})") class MockAnythingTest(unittest.TestCase): - """Verify that the MockAnything class works as expected.""" + """Verify that the MockAnything class works as expected.""" - def setUp(self): - self.mock_object = mox.MockAnything() + def setUp(self): + self.mock_object = mox.MockAnything() - def testRepr(self): - """Calling repr on a MockAnything instance must work.""" - self.assertEqual('', repr(self.mock_object)) + def testRepr(self): + """Calling repr on a MockAnything instance must work.""" + self.assertEqual('', repr(self.mock_object)) - def testCanMockStr(self): - self.mock_object.__str__().AndReturn("foo") - self.mock_object._Replay() - actual = str(self.mock_object) - self.mock_object._Verify() - self.assertEqual("foo", actual) + def testCanMockStr(self): + self.mock_object.__str__().AndReturn("foo") + self.mock_object._Replay() + actual = str(self.mock_object) + self.mock_object._Verify() + self.assertEqual("foo", actual) - def testSetupMode(self): - """Verify the mock will accept any call.""" - self.mock_object.NonsenseCall() - self.assertTrue(len(self.mock_object._expected_calls_queue) == 1) + def testSetupMode(self): + """Verify the mock will accept any call.""" + self.mock_object.NonsenseCall() + self.assertTrue(len(self.mock_object._expected_calls_queue) == 1) - def testReplayWithExpectedCall(self): - """Verify the mock replays method calls as expected.""" - self.mock_object.ValidCall() # setup method call - self.mock_object._Replay() # start replay mode - self.mock_object.ValidCall() # make method call + def testReplayWithExpectedCall(self): + """Verify the mock replays method calls as expected.""" + self.mock_object.ValidCall() # setup method call + self.mock_object._Replay() # start replay mode + self.mock_object.ValidCall() # make method call - def testReplayWithUnexpectedCall(self): - """Unexpected method calls should raise UnexpectedMethodCallError.""" - self.mock_object.ValidCall() # setup method call - self.mock_object._Replay() # start replay mode - self.assertRaises(mox.UnexpectedMethodCallError, - self.mock_object.OtherValidCall) + def testReplayWithUnexpectedCall(self): + """Unexpected method calls should raise UnexpectedMethodCallError.""" + self.mock_object.ValidCall() # setup method call + self.mock_object._Replay() # start replay mode + self.assertRaises(mox.UnexpectedMethodCallError, + self.mock_object.OtherValidCall) - def testVerifyWithCompleteReplay(self): - """Verify should not raise an exception for a valid replay.""" - self.mock_object.ValidCall() # setup method call - self.mock_object._Replay() # start replay mode - self.mock_object.ValidCall() # make method call - self.mock_object._Verify() + def testVerifyWithCompleteReplay(self): + """Verify should not raise an exception for a valid replay.""" + self.mock_object.ValidCall() # setup method call + self.mock_object._Replay() # start replay mode + self.mock_object.ValidCall() # make method call + self.mock_object._Verify() - def testVerifyWithIncompleteReplay(self): - """Verify should raise an exception if the replay was not complete.""" - self.mock_object.ValidCall() # setup method call - self.mock_object._Replay() # start replay mode - # ValidCall() is never made - self.assertRaises(mox.ExpectedMethodCallsError, self.mock_object._Verify) + def testVerifyWithIncompleteReplay(self): + """Verify should raise an exception if the replay was not complete.""" + self.mock_object.ValidCall() # setup method call + self.mock_object._Replay() # start replay mode + # ValidCall() is never made + self.assertRaises(mox.ExpectedMethodCallsError, self.mock_object._Verify) - def testSpecialClassMethod(self): - """Verify should not raise an exception when special methods are used.""" - self.mock_object[1].AndReturn(True) - self.mock_object._Replay() - returned_val = self.mock_object[1] - self.assertTrue(returned_val) - self.mock_object._Verify() + def testSpecialClassMethod(self): + """Verify should not raise an exception when special methods are used.""" + self.mock_object[1].AndReturn(True) + self.mock_object._Replay() + returned_val = self.mock_object[1] + self.assertTrue(returned_val) + self.mock_object._Verify() - def testNonzero(self): - """You should be able to use the mock object in an if.""" - self.mock_object._Replay() - if self.mock_object: - pass + def testNonzero(self): + """You should be able to use the mock object in an if.""" + self.mock_object._Replay() + if self.mock_object: + pass - def testNotNone(self): - """Mock should be comparable to None.""" - self.mock_object._Replay() - if self.mock_object is not None: - pass + def testNotNone(self): + """Mock should be comparable to None.""" + self.mock_object._Replay() + if self.mock_object is not None: + pass - if self.mock_object is None: - pass + if self.mock_object is None: + pass - def testEquals(self): - """A mock should be able to compare itself to another object.""" - self.mock_object._Replay() - self.assertEqual(self.mock_object, self.mock_object) + def testEquals(self): + """A mock should be able to compare itself to another object.""" + self.mock_object._Replay() + self.assertEqual(self.mock_object, self.mock_object) - def testEqualsMockFailure(self): - """Verify equals identifies unequal objects.""" - self.mock_object.SillyCall() - self.mock_object._Replay() - self.assertNotEqual(self.mock_object, mox.MockAnything()) + def testEqualsMockFailure(self): + """Verify equals identifies unequal objects.""" + self.mock_object.SillyCall() + self.mock_object._Replay() + self.assertNotEqual(self.mock_object, mox.MockAnything()) - def testEqualsInstanceFailure(self): - """Verify equals identifies that objects are different instances.""" - self.mock_object._Replay() - self.assertNotEqual(self.mock_object, TestClass()) + def testEqualsInstanceFailure(self): + """Verify equals identifies that objects are different instances.""" + self.mock_object._Replay() + self.assertNotEqual(self.mock_object, TestClass()) - def testNotEquals(self): - """Verify not equals works.""" - self.mock_object._Replay() - self.assertFalse(self.mock_object != self.mock_object) + def testNotEquals(self): + """Verify not equals works.""" + self.mock_object._Replay() + self.assertFalse(self.mock_object != self.mock_object) - def testNestedMockCallsRecordedSerially(self): - """Test that nested calls work when recorded serially.""" - self.mock_object.CallInner().AndReturn(1) - self.mock_object.CallOuter(1) - self.mock_object._Replay() + def testNestedMockCallsRecordedSerially(self): + """Test that nested calls work when recorded serially.""" + self.mock_object.CallInner().AndReturn(1) + self.mock_object.CallOuter(1) + self.mock_object._Replay() - self.mock_object.CallOuter(self.mock_object.CallInner()) + self.mock_object.CallOuter(self.mock_object.CallInner()) - self.mock_object._Verify() + self.mock_object._Verify() - def testNestedMockCallsRecordedNested(self): - """Test that nested cals work when recorded in a nested fashion.""" - self.mock_object.CallOuter(self.mock_object.CallInner().AndReturn(1)) - self.mock_object._Replay() + def testNestedMockCallsRecordedNested(self): + """Test that nested cals work when recorded in a nested fashion.""" + self.mock_object.CallOuter(self.mock_object.CallInner().AndReturn(1)) + self.mock_object._Replay() - self.mock_object.CallOuter(self.mock_object.CallInner()) + self.mock_object.CallOuter(self.mock_object.CallInner()) - self.mock_object._Verify() + self.mock_object._Verify() - def testIsCallable(self): - """Test that MockAnything can even mock a simple callable. + def testIsCallable(self): + """Test that MockAnything can even mock a simple callable. - This is handy for "stubbing out" a method in a module with a mock, and - verifying that it was called. - """ - self.mock_object().AndReturn('mox0rd') - self.mock_object._Replay() + This is handy for "stubbing out" a method in a module with a mock, and + verifying that it was called. + """ + self.mock_object().AndReturn('mox0rd') + self.mock_object._Replay() - self.assertEqual('mox0rd', self.mock_object()) + self.assertEqual('mox0rd', self.mock_object()) - self.mock_object._Verify() + self.mock_object._Verify() - def testIsReprable(self): - """Test that MockAnythings can be repr'd without causing a failure.""" - self.assertTrue('MockAnything' in repr(self.mock_object)) + def testIsReprable(self): + """Test that MockAnythings can be repr'd without causing a failure.""" + self.assertTrue('MockAnything' in repr(self.mock_object)) class MethodCheckerTest(unittest.TestCase): - """Tests MockMethod's use of MethodChecker method.""" + """Tests MockMethod's use of MethodChecker method.""" - def testUnboundMethodsRequiresInstance(self): - # SKIP TEST IN PYTHON 2.x (Ugly hack for python 2.6) - # REASON: semantics for unbound methods has changed only in Python 3 - # so this test in earlier versions is invald - if sys.version_info < (3, 0): - return + def testUnboundMethodsRequiresInstance(self): + # SKIP TEST IN PYTHON 2.x (Ugly hack for python 2.6) + # REASON: semantics for unbound methods has changed only in Python 3 + # so this test in earlier versions is invald + if sys.version_info < (3, 0): + return - instance = CheckCallTestClass() - method = mox.MockMethod('NoParameters', [], False, - CheckCallTestClass.NoParameters) + instance = CheckCallTestClass() + method = mox.MockMethod('NoParameters', [], False, + CheckCallTestClass.NoParameters) - self.assertRaises(AttributeError, method) - method(instance) - self.assertRaises(AttributeError, method, instance, 1) + self.assertRaises(AttributeError, method) + method(instance) + self.assertRaises(AttributeError, method, instance, 1) - def testNoParameters(self): - method = mox.MockMethod('NoParameters', [], False, - CheckCallTestClass.NoParameters, - class_to_bind=CheckCallTestClass) - method() - self.assertRaises(AttributeError, method, 1) - self.assertRaises(AttributeError, method, 1, 2) - self.assertRaises(AttributeError, method, a=1) - self.assertRaises(AttributeError, method, 1, b=2) + def testNoParameters(self): + method = mox.MockMethod('NoParameters', [], False, + CheckCallTestClass.NoParameters, + class_to_bind=CheckCallTestClass) + method() + self.assertRaises(AttributeError, method, 1) + self.assertRaises(AttributeError, method, 1, 2) + self.assertRaises(AttributeError, method, a=1) + self.assertRaises(AttributeError, method, 1, b=2) - def testOneParameter(self): - method = mox.MockMethod('OneParameter', [], False, - CheckCallTestClass.OneParameter, - class_to_bind=CheckCallTestClass) - self.assertRaises(AttributeError, method) - method(1) - method(a=1) - self.assertRaises(AttributeError, method, b=1) - self.assertRaises(AttributeError, method, 1, 2) - self.assertRaises(AttributeError, method, 1, a=2) - self.assertRaises(AttributeError, method, 1, b=2) + def testOneParameter(self): + method = mox.MockMethod('OneParameter', [], False, + CheckCallTestClass.OneParameter, + class_to_bind=CheckCallTestClass) + self.assertRaises(AttributeError, method) + method(1) + method(a=1) + self.assertRaises(AttributeError, method, b=1) + self.assertRaises(AttributeError, method, 1, 2) + self.assertRaises(AttributeError, method, 1, a=2) + self.assertRaises(AttributeError, method, 1, b=2) - def testTwoParameters(self): - method = mox.MockMethod('TwoParameters', [], False, - CheckCallTestClass.TwoParameters, - class_to_bind=CheckCallTestClass) - self.assertRaises(AttributeError, method) - self.assertRaises(AttributeError, method, 1) - self.assertRaises(AttributeError, method, a=1) - self.assertRaises(AttributeError, method, b=1) - method(1, 2) - method(1, b=2) - method(a=1, b=2) - method(b=2, a=1) - self.assertRaises(AttributeError, method, b=2, c=3) - self.assertRaises(AttributeError, method, a=1, b=2, c=3) - self.assertRaises(AttributeError, method, 1, 2, 3) - self.assertRaises(AttributeError, method, 1, 2, 3, 4) - self.assertRaises(AttributeError, method, 3, a=1, b=2) + def testTwoParameters(self): + method = mox.MockMethod('TwoParameters', [], False, + CheckCallTestClass.TwoParameters, + class_to_bind=CheckCallTestClass) + self.assertRaises(AttributeError, method) + self.assertRaises(AttributeError, method, 1) + self.assertRaises(AttributeError, method, a=1) + self.assertRaises(AttributeError, method, b=1) + method(1, 2) + method(1, b=2) + method(a=1, b=2) + method(b=2, a=1) + self.assertRaises(AttributeError, method, b=2, c=3) + self.assertRaises(AttributeError, method, a=1, b=2, c=3) + self.assertRaises(AttributeError, method, 1, 2, 3) + self.assertRaises(AttributeError, method, 1, 2, 3, 4) + self.assertRaises(AttributeError, method, 3, a=1, b=2) - def testOneDefaultValue(self): - method = mox.MockMethod('OneDefaultValue', [], False, - CheckCallTestClass.OneDefaultValue, - class_to_bind=CheckCallTestClass) - method() - method(1) - method(a=1) - self.assertRaises(AttributeError, method, b=1) - self.assertRaises(AttributeError, method, 1, 2) - self.assertRaises(AttributeError, method, 1, a=2) - self.assertRaises(AttributeError, method, 1, b=2) + def testOneDefaultValue(self): + method = mox.MockMethod('OneDefaultValue', [], False, + CheckCallTestClass.OneDefaultValue, + class_to_bind=CheckCallTestClass) + method() + method(1) + method(a=1) + self.assertRaises(AttributeError, method, b=1) + self.assertRaises(AttributeError, method, 1, 2) + self.assertRaises(AttributeError, method, 1, a=2) + self.assertRaises(AttributeError, method, 1, b=2) - def testTwoDefaultValues(self): - method = mox.MockMethod('TwoDefaultValues', [], False, - CheckCallTestClass.TwoDefaultValues, - class_to_bind=CheckCallTestClass) - self.assertRaises(AttributeError, method) - self.assertRaises(AttributeError, method, c=3) - self.assertRaises(AttributeError, method, 1) - self.assertRaises(AttributeError, method, 1, d=4) - self.assertRaises(AttributeError, method, 1, d=4, c=3) - method(1, 2) - method(a=1, b=2) - method(1, 2, 3) - method(1, 2, 3, 4) - method(1, 2, c=3) - method(1, 2, c=3, d=4) - method(1, 2, d=4, c=3) - method(d=4, c=3, a=1, b=2) - self.assertRaises(AttributeError, method, 1, 2, 3, 4, 5) - self.assertRaises(AttributeError, method, 1, 2, e=9) - self.assertRaises(AttributeError, method, a=1, b=2, e=9) + def testTwoDefaultValues(self): + method = mox.MockMethod('TwoDefaultValues', [], False, + CheckCallTestClass.TwoDefaultValues, + class_to_bind=CheckCallTestClass) + self.assertRaises(AttributeError, method) + self.assertRaises(AttributeError, method, c=3) + self.assertRaises(AttributeError, method, 1) + self.assertRaises(AttributeError, method, 1, d=4) + self.assertRaises(AttributeError, method, 1, d=4, c=3) + method(1, 2) + method(a=1, b=2) + method(1, 2, 3) + method(1, 2, 3, 4) + method(1, 2, c=3) + method(1, 2, c=3, d=4) + method(1, 2, d=4, c=3) + method(d=4, c=3, a=1, b=2) + self.assertRaises(AttributeError, method, 1, 2, 3, 4, 5) + self.assertRaises(AttributeError, method, 1, 2, e=9) + self.assertRaises(AttributeError, method, a=1, b=2, e=9) - def testArgs(self): - method = mox.MockMethod('Args', [], False, CheckCallTestClass.Args, - class_to_bind=CheckCallTestClass) - self.assertRaises(AttributeError, method) - self.assertRaises(AttributeError, method, 1) - method(1, 2) - method(a=1, b=2) - method(1, 2, 3) - method(1, 2, 3, 4) - self.assertRaises(AttributeError, method, 1, 2, a=3) - self.assertRaises(AttributeError, method, 1, 2, c=3) + def testArgs(self): + method = mox.MockMethod('Args', [], False, CheckCallTestClass.Args, + class_to_bind=CheckCallTestClass) + self.assertRaises(AttributeError, method) + self.assertRaises(AttributeError, method, 1) + method(1, 2) + method(a=1, b=2) + method(1, 2, 3) + method(1, 2, 3, 4) + self.assertRaises(AttributeError, method, 1, 2, a=3) + self.assertRaises(AttributeError, method, 1, 2, c=3) - def testKwargs(self): - method = mox.MockMethod('Kwargs', [], False, CheckCallTestClass.Kwargs, - class_to_bind=CheckCallTestClass) - self.assertRaises(AttributeError, method) - method(1) - method(1, 2) - method(a=1, b=2) - method(b=2, a=1) - self.assertRaises(AttributeError, method, 1, 2, 3) - self.assertRaises(AttributeError, method, 1, 2, a=3) - method(1, 2, c=3) - method(a=1, b=2, c=3) - method(c=3, a=1, b=2) - method(a=1, b=2, c=3, d=4) - self.assertRaises(AttributeError, method, 1, 2, 3, 4) + def testKwargs(self): + method = mox.MockMethod('Kwargs', [], False, CheckCallTestClass.Kwargs, + class_to_bind=CheckCallTestClass) + self.assertRaises(AttributeError, method) + method(1) + method(1, 2) + method(a=1, b=2) + method(b=2, a=1) + self.assertRaises(AttributeError, method, 1, 2, 3) + self.assertRaises(AttributeError, method, 1, 2, a=3) + method(1, 2, c=3) + method(a=1, b=2, c=3) + method(c=3, a=1, b=2) + method(a=1, b=2, c=3, d=4) + self.assertRaises(AttributeError, method, 1, 2, 3, 4) - def testArgsAndKwargs(self): - method = mox.MockMethod('ArgsAndKwargs', [], False, - CheckCallTestClass.ArgsAndKwargs, - class_to_bind=CheckCallTestClass) - self.assertRaises(AttributeError, method) - method(1) - method(1, 2) - method(1, 2, 3) - method(a=1) - method(1, b=2) - self.assertRaises(AttributeError, method, 1, a=2) - method(b=2, a=1) - method(c=3, b=2, a=1) - method(1, 2, c=3) + def testArgsAndKwargs(self): + method = mox.MockMethod('ArgsAndKwargs', [], False, + CheckCallTestClass.ArgsAndKwargs, + class_to_bind=CheckCallTestClass) + self.assertRaises(AttributeError, method) + method(1) + method(1, 2) + method(1, 2, 3) + method(a=1) + method(1, b=2) + self.assertRaises(AttributeError, method, 1, a=2) + method(b=2, a=1) + method(c=3, b=2, a=1) + method(1, 2, c=3) class CheckCallTestClass(object): - def NoParameters(self): - pass + def NoParameters(self): + pass - def OneParameter(self, a): - pass + def OneParameter(self, a): + pass - def TwoParameters(self, a, b): - pass + def TwoParameters(self, a, b): + pass - def OneDefaultValue(self, a=1): - pass + def OneDefaultValue(self, a=1): + pass - def TwoDefaultValues(self, a, b, c=1, d=2): - pass + def TwoDefaultValues(self, a, b, c=1, d=2): + pass - def Args(self, a, b, *args): - pass + def Args(self, a, b, *args): + pass - def Kwargs(self, a, b=2, **kwargs): - pass + def Kwargs(self, a, b=2, **kwargs): + pass - def ArgsAndKwargs(self, a, *args, **kwargs): - pass + def ArgsAndKwargs(self, a, *args, **kwargs): + pass class MockObjectTest(unittest.TestCase): - """Verify that the MockObject class works as exepcted.""" - - def setUp(self): - self.mock_object = mox.MockObject(TestClass) - - def testSetupModeWithValidCall(self): - """Verify the mock object properly mocks a basic method call.""" - self.mock_object.ValidCall() - self.assertTrue(len(self.mock_object._expected_calls_queue) == 1) - - def testSetupModeWithInvalidCall(self): - """UnknownMethodCallError should be raised for a non-member method call. - """ - # Note: assertRaises does not catch exceptions thrown by MockObject's - # __getattr__ - try: - self.mock_object.InvalidCall() - self.fail("No exception thrown, expected UnknownMethodCallError") - except mox.UnknownMethodCallError: - pass - except Exception: - self.fail("Wrong exception type thrown, expected UnknownMethodCallError") - - def testReplayWithInvalidCall(self): - """UnknownMethodCallError should be raised for a non-member method call. - """ - self.mock_object.ValidCall() # setup method call - self.mock_object._Replay() # start replay mode - # Note: assertRaises does not catch exceptions thrown by MockObject's - # __getattr__ - try: - self.mock_object.InvalidCall() - self.fail("No exception thrown, expected UnknownMethodCallError") - except mox.UnknownMethodCallError: - pass - except Exception: - self.fail("Wrong exception type thrown, expected UnknownMethodCallError") - - def testIsInstance(self): - """Mock should be able to pass as an instance of the mocked class.""" - self.assertTrue(isinstance(self.mock_object, TestClass)) - - def testFindValidMethods(self): - """Mock should be able to mock all public methods.""" - self.assertTrue('ValidCall' in self.mock_object._known_methods) - self.assertTrue('OtherValidCall' in self.mock_object._known_methods) - self.assertTrue('MyClassMethod' in self.mock_object._known_methods) - self.assertTrue('MyStaticMethod' in self.mock_object._known_methods) - self.assertTrue('_ProtectedCall' in self.mock_object._known_methods) - self.assertTrue('__PrivateCall' not in self.mock_object._known_methods) - self.assertTrue( - '_TestClass__PrivateCall' in self.mock_object._known_methods) - - def testFindsSuperclassMethods(self): - """Mock should be able to mock superclasses methods.""" - self.mock_object = mox.MockObject(ChildClass) - self.assertTrue('ValidCall' in self.mock_object._known_methods) - self.assertTrue('OtherValidCall' in self.mock_object._known_methods) - self.assertTrue('MyClassMethod' in self.mock_object._known_methods) - self.assertTrue('ChildValidCall' in self.mock_object._known_methods) - - def testAccessClassVariables(self): - """Class variables should be accessible through the mock.""" - self.assertTrue('SOME_CLASS_VAR' in self.mock_object._known_vars) - self.assertTrue('_PROTECTED_CLASS_VAR' in self.mock_object._known_vars) - self.assertEqual('test_value', self.mock_object.SOME_CLASS_VAR) - - def testEquals(self): - """A mock should be able to compare itself to another object.""" - self.mock_object._Replay() - self.assertEqual(self.mock_object, self.mock_object) - - def testEqualsMockFailure(self): - """Verify equals identifies unequal objects.""" - self.mock_object.ValidCall() - self.mock_object._Replay() - self.assertNotEqual(self.mock_object, mox.MockObject(TestClass)) - - def testEqualsInstanceFailure(self): - """Verify equals identifies that objects are different instances.""" - self.mock_object._Replay() - self.assertNotEqual(self.mock_object, TestClass()) - - def testNotEquals(self): - """Verify not equals works.""" - self.mock_object._Replay() - self.assertFalse(self.mock_object != self.mock_object) - - def testMockSetItem_ExpectedSetItem_Success(self): - """Test that __setitem__() gets mocked in Dummy. + """Verify that the MockObject class works as exepcted.""" + + def setUp(self): + self.mock_object = mox.MockObject(TestClass) + + def testSetupModeWithValidCall(self): + """Verify the mock object properly mocks a basic method call.""" + self.mock_object.ValidCall() + self.assertTrue(len(self.mock_object._expected_calls_queue) == 1) + + def testSetupModeWithInvalidCall(self): + """UnknownMethodCallError should be raised for a non-member method call. + """ + # Note: assertRaises does not catch exceptions thrown by MockObject's + # __getattr__ + try: + self.mock_object.InvalidCall() + self.fail("No exception thrown, expected UnknownMethodCallError") + except mox.UnknownMethodCallError: + pass + except Exception: + self.fail("Wrong exception type thrown, expected UnknownMethodCallError") + + def testReplayWithInvalidCall(self): + """UnknownMethodCallError should be raised for a non-member method call. + """ + self.mock_object.ValidCall() # setup method call + self.mock_object._Replay() # start replay mode + # Note: assertRaises does not catch exceptions thrown by MockObject's + # __getattr__ + try: + self.mock_object.InvalidCall() + self.fail("No exception thrown, expected UnknownMethodCallError") + except mox.UnknownMethodCallError: + pass + except Exception: + self.fail("Wrong exception type thrown, expected UnknownMethodCallError") + + def testIsInstance(self): + """Mock should be able to pass as an instance of the mocked class.""" + self.assertTrue(isinstance(self.mock_object, TestClass)) + + def testFindValidMethods(self): + """Mock should be able to mock all public methods.""" + self.assertTrue('ValidCall' in self.mock_object._known_methods) + self.assertTrue('OtherValidCall' in self.mock_object._known_methods) + self.assertTrue('MyClassMethod' in self.mock_object._known_methods) + self.assertTrue('MyStaticMethod' in self.mock_object._known_methods) + self.assertTrue('_ProtectedCall' in self.mock_object._known_methods) + self.assertTrue('__PrivateCall' not in self.mock_object._known_methods) + self.assertTrue( + '_TestClass__PrivateCall' in self.mock_object._known_methods) + + def testFindsSuperclassMethods(self): + """Mock should be able to mock superclasses methods.""" + self.mock_object = mox.MockObject(ChildClass) + self.assertTrue('ValidCall' in self.mock_object._known_methods) + self.assertTrue('OtherValidCall' in self.mock_object._known_methods) + self.assertTrue('MyClassMethod' in self.mock_object._known_methods) + self.assertTrue('ChildValidCall' in self.mock_object._known_methods) + + def testAccessClassVariables(self): + """Class variables should be accessible through the mock.""" + self.assertTrue('SOME_CLASS_VAR' in self.mock_object._known_vars) + self.assertTrue('_PROTECTED_CLASS_VAR' in self.mock_object._known_vars) + self.assertEqual('test_value', self.mock_object.SOME_CLASS_VAR) + + def testEquals(self): + """A mock should be able to compare itself to another object.""" + self.mock_object._Replay() + self.assertEqual(self.mock_object, self.mock_object) + + def testEqualsMockFailure(self): + """Verify equals identifies unequal objects.""" + self.mock_object.ValidCall() + self.mock_object._Replay() + self.assertNotEqual(self.mock_object, mox.MockObject(TestClass)) + + def testEqualsInstanceFailure(self): + """Verify equals identifies that objects are different instances.""" + self.mock_object._Replay() + self.assertNotEqual(self.mock_object, TestClass()) + + def testNotEquals(self): + """Verify not equals works.""" + self.mock_object._Replay() + self.assertFalse(self.mock_object != self.mock_object) + + def testMockSetItem_ExpectedSetItem_Success(self): + """Test that __setitem__() gets mocked in Dummy. - In this test, _Verify() succeeds. - """ - dummy = mox.MockObject(TestClass) - dummy['X'] = 'Y' - - dummy._Replay() + In this test, _Verify() succeeds. + """ + dummy = mox.MockObject(TestClass) + dummy['X'] = 'Y' + + dummy._Replay() - dummy['X'] = 'Y' + dummy['X'] = 'Y' - dummy._Verify() + dummy._Verify() - def testMockSetItem_ExpectedSetItem_NoSuccess(self): - """Test that __setitem__() gets mocked in Dummy. + def testMockSetItem_ExpectedSetItem_NoSuccess(self): + """Test that __setitem__() gets mocked in Dummy. - In this test, _Verify() fails. - """ - dummy = mox.MockObject(TestClass) - dummy['X'] = 'Y' + In this test, _Verify() fails. + """ + dummy = mox.MockObject(TestClass) + dummy['X'] = 'Y' - dummy._Replay() + dummy._Replay() - # NOT doing dummy['X'] = 'Y' + # NOT doing dummy['X'] = 'Y' - self.assertRaises(mox.ExpectedMethodCallsError, dummy._Verify) + self.assertRaises(mox.ExpectedMethodCallsError, dummy._Verify) - def testMockSetItem_ExpectedNoSetItem_Success(self): - """Test that __setitem__() gets mocked in Dummy.""" - dummy = mox.MockObject(TestClass) - # NOT doing dummy['X'] = 'Y' + def testMockSetItem_ExpectedNoSetItem_Success(self): + """Test that __setitem__() gets mocked in Dummy.""" + dummy = mox.MockObject(TestClass) + # NOT doing dummy['X'] = 'Y' - dummy._Replay() + dummy._Replay() - def call(): - dummy['X'] = 'Y' + def call(): + dummy['X'] = 'Y' - self.assertRaises(mox.UnexpectedMethodCallError, call) + self.assertRaises(mox.UnexpectedMethodCallError, call) - def testMockSetItem_ExpectedNoSetItem_NoSuccess(self): - """Test that __setitem__() gets mocked in Dummy. + def testMockSetItem_ExpectedNoSetItem_NoSuccess(self): + """Test that __setitem__() gets mocked in Dummy. - In this test, _Verify() fails. - """ - dummy = mox.MockObject(TestClass) - # NOT doing dummy['X'] = 'Y' + In this test, _Verify() fails. + """ + dummy = mox.MockObject(TestClass) + # NOT doing dummy['X'] = 'Y' - dummy._Replay() + dummy._Replay() - # NOT doing dummy['X'] = 'Y' + # NOT doing dummy['X'] = 'Y' - dummy._Verify() + dummy._Verify() - def testMockSetItem_ExpectedSetItem_NonmatchingParameters(self): - """Test that __setitem__() fails if other parameters are expected.""" - dummy = mox.MockObject(TestClass) - dummy['X'] = 'Y' + def testMockSetItem_ExpectedSetItem_NonmatchingParameters(self): + """Test that __setitem__() fails if other parameters are expected.""" + dummy = mox.MockObject(TestClass) + dummy['X'] = 'Y' - dummy._Replay() + dummy._Replay() - def call(): - dummy['wrong'] = 'Y' + def call(): + dummy['wrong'] = 'Y' - self.assertRaises(mox.UnexpectedMethodCallError, call) + self.assertRaises(mox.UnexpectedMethodCallError, call) - dummy._Verify() + dummy._Verify() - def testMockSetItem_WithSubClassOfNewStyleClass(self): - class NewStyleTestClass(object): - def __init__(self): - self.my_dict = {} + def testMockSetItem_WithSubClassOfNewStyleClass(self): + class NewStyleTestClass(object): + def __init__(self): + self.my_dict = {} - def __setitem__(self, key, value): - self.my_dict[key], value + def __setitem__(self, key, value): + self.my_dict[key], value - class TestSubClass(NewStyleTestClass): - pass + class TestSubClass(NewStyleTestClass): + pass - dummy = mox.MockObject(TestSubClass) - dummy[1] = 2 - dummy._Replay() - dummy[1] = 2 - dummy._Verify() + dummy = mox.MockObject(TestSubClass) + dummy[1] = 2 + dummy._Replay() + dummy[1] = 2 + dummy._Verify() - def testMockGetItem_ExpectedGetItem_Success(self): - """Test that __getitem__() gets mocked in Dummy. + def testMockGetItem_ExpectedGetItem_Success(self): + """Test that __getitem__() gets mocked in Dummy. - In this test, _Verify() succeeds. - """ - dummy = mox.MockObject(TestClass) - dummy['X'].AndReturn('value') + In this test, _Verify() succeeds. + """ + dummy = mox.MockObject(TestClass) + dummy['X'].AndReturn('value') - dummy._Replay() + dummy._Replay() - self.assertEqual(dummy['X'], 'value') + self.assertEqual(dummy['X'], 'value') - dummy._Verify() + dummy._Verify() - def testMockGetItem_ExpectedGetItem_NoSuccess(self): - """Test that __getitem__() gets mocked in Dummy. + def testMockGetItem_ExpectedGetItem_NoSuccess(self): + """Test that __getitem__() gets mocked in Dummy. - In this test, _Verify() fails. - """ - dummy = mox.MockObject(TestClass) - dummy['X'].AndReturn('value') + In this test, _Verify() fails. + """ + dummy = mox.MockObject(TestClass) + dummy['X'].AndReturn('value') - dummy._Replay() + dummy._Replay() - # NOT doing dummy['X'] + # NOT doing dummy['X'] - self.assertRaises(mox.ExpectedMethodCallsError, dummy._Verify) + self.assertRaises(mox.ExpectedMethodCallsError, dummy._Verify) - def testMockGetItem_ExpectedNoGetItem_NoSuccess(self): - """Test that __getitem__() gets mocked in Dummy.""" - dummy = mox.MockObject(TestClass) - # NOT doing dummy['X'] + def testMockGetItem_ExpectedNoGetItem_NoSuccess(self): + """Test that __getitem__() gets mocked in Dummy.""" + dummy = mox.MockObject(TestClass) + # NOT doing dummy['X'] - dummy._Replay() + dummy._Replay() - def call(): - return dummy['X'] + def call(): + return dummy['X'] - self.assertRaises(mox.UnexpectedMethodCallError, call) + self.assertRaises(mox.UnexpectedMethodCallError, call) - def testMockGetItem_ExpectedGetItem_NonmatchingParameters(self): - """Test that __getitem__() fails if other parameters are expected.""" - dummy = mox.MockObject(TestClass) - dummy['X'].AndReturn('value') + def testMockGetItem_ExpectedGetItem_NonmatchingParameters(self): + """Test that __getitem__() fails if other parameters are expected.""" + dummy = mox.MockObject(TestClass) + dummy['X'].AndReturn('value') - dummy._Replay() + dummy._Replay() - def call(): - return dummy['wrong'] + def call(): + return dummy['wrong'] - self.assertRaises(mox.UnexpectedMethodCallError, call) + self.assertRaises(mox.UnexpectedMethodCallError, call) - dummy._Verify() + dummy._Verify() - def testMockGetItem_WithSubClassOfNewStyleClass(self): - class NewStyleTestClass(object): - def __getitem__(self, key): - return {1: '1', 2: '2'}[key] + def testMockGetItem_WithSubClassOfNewStyleClass(self): + class NewStyleTestClass(object): + def __getitem__(self, key): + return {1: '1', 2: '2'}[key] - class TestSubClass(NewStyleTestClass): - pass + class TestSubClass(NewStyleTestClass): + pass - dummy = mox.MockObject(TestSubClass) - dummy[1].AndReturn('3') + dummy = mox.MockObject(TestSubClass) + dummy[1].AndReturn('3') - dummy._Replay() - self.assertEqual('3', dummy.__getitem__(1)) - dummy._Verify() + dummy._Replay() + self.assertEqual('3', dummy.__getitem__(1)) + dummy._Verify() - def testMockIter_ExpectedIter_Success(self): - """Test that __iter__() gets mocked in Dummy. + def testMockIter_ExpectedIter_Success(self): + """Test that __iter__() gets mocked in Dummy. - In this test, _Verify() succeeds. - """ - dummy = mox.MockObject(TestClass) - iter(dummy).AndReturn(iter(['X', 'Y'])) + In this test, _Verify() succeeds. + """ + dummy = mox.MockObject(TestClass) + iter(dummy).AndReturn(iter(['X', 'Y'])) - dummy._Replay() + dummy._Replay() - self.assertEqual([x for x in dummy], ['X', 'Y']) + self.assertEqual([x for x in dummy], ['X', 'Y']) - dummy._Verify() + dummy._Verify() - def testMockContains_ExpectedContains_Success(self): - """Test that __contains__ gets mocked in Dummy. + def testMockContains_ExpectedContains_Success(self): + """Test that __contains__ gets mocked in Dummy. - In this test, _Verify() succeeds. - """ - dummy = mox.MockObject(TestClass) - dummy.__contains__('X').AndReturn(True) + In this test, _Verify() succeeds. + """ + dummy = mox.MockObject(TestClass) + dummy.__contains__('X').AndReturn(True) - dummy._Replay() + dummy._Replay() - self.assertTrue('X' in dummy) + self.assertTrue('X' in dummy) - dummy._Verify() + dummy._Verify() - def testMockContains_ExpectedContains_NoSuccess(self): - """Test that __contains__() gets mocked in Dummy. + def testMockContains_ExpectedContains_NoSuccess(self): + """Test that __contains__() gets mocked in Dummy. - In this test, _Verify() fails. - """ - dummy = mox.MockObject(TestClass) - dummy.__contains__('X').AndReturn('True') + In this test, _Verify() fails. + """ + dummy = mox.MockObject(TestClass) + dummy.__contains__('X').AndReturn('True') - dummy._Replay() + dummy._Replay() - # NOT doing 'X' in dummy + # NOT doing 'X' in dummy - self.assertRaises(mox.ExpectedMethodCallsError, dummy._Verify) + self.assertRaises(mox.ExpectedMethodCallsError, dummy._Verify) - def testMockContains_ExpectedContains_NonmatchingParameter(self): - """Test that __contains__ fails if other parameters are expected.""" - dummy = mox.MockObject(TestClass) - dummy.__contains__('X').AndReturn(True) + def testMockContains_ExpectedContains_NonmatchingParameter(self): + """Test that __contains__ fails if other parameters are expected.""" + dummy = mox.MockObject(TestClass) + dummy.__contains__('X').AndReturn(True) - dummy._Replay() + dummy._Replay() - def call(): - return 'Y' in dummy + def call(): + return 'Y' in dummy - self.assertRaises(mox.UnexpectedMethodCallError, call) + self.assertRaises(mox.UnexpectedMethodCallError, call) - dummy._Verify() + dummy._Verify() - def testMockIter_ExpectedIter_NoSuccess(self): - """Test that __iter__() gets mocked in Dummy. + def testMockIter_ExpectedIter_NoSuccess(self): + """Test that __iter__() gets mocked in Dummy. - In this test, _Verify() fails. - """ - dummy = mox.MockObject(TestClass) - iter(dummy).AndReturn(iter(['X', 'Y'])) + In this test, _Verify() fails. + """ + dummy = mox.MockObject(TestClass) + iter(dummy).AndReturn(iter(['X', 'Y'])) - dummy._Replay() + dummy._Replay() - # NOT doing self.assertEqual([x for x in dummy], ['X', 'Y']) + # NOT doing self.assertEqual([x for x in dummy], ['X', 'Y']) - self.assertRaises(mox.ExpectedMethodCallsError, dummy._Verify) + self.assertRaises(mox.ExpectedMethodCallsError, dummy._Verify) - def testMockIter_ExpectedNoIter_NoSuccess(self): - """Test that __iter__() gets mocked in Dummy.""" - dummy = mox.MockObject(TestClass) - # NOT doing iter(dummy) + def testMockIter_ExpectedNoIter_NoSuccess(self): + """Test that __iter__() gets mocked in Dummy.""" + dummy = mox.MockObject(TestClass) + # NOT doing iter(dummy) - dummy._Replay() + dummy._Replay() - def call(): - return [x for x in dummy] - self.assertRaises(mox.UnexpectedMethodCallError, call) + def call(): + return [x for x in dummy] + self.assertRaises(mox.UnexpectedMethodCallError, call) - def testMockIter_ExpectedGetItem_Success(self): - """Test that __iter__() gets mocked in Dummy using getitem.""" - dummy = mox.MockObject(SubscribtableNonIterableClass) - dummy[0].AndReturn('a') - dummy[1].AndReturn('b') - dummy[2].AndRaise(IndexError) + def testMockIter_ExpectedGetItem_Success(self): + """Test that __iter__() gets mocked in Dummy using getitem.""" + dummy = mox.MockObject(SubscribtableNonIterableClass) + dummy[0].AndReturn('a') + dummy[1].AndReturn('b') + dummy[2].AndRaise(IndexError) - dummy._Replay() - self.assertEqual(['a', 'b'], [x for x in dummy]) - dummy._Verify() + dummy._Replay() + self.assertEqual(['a', 'b'], [x for x in dummy]) + dummy._Verify() - def testMockIter_ExpectedNoGetItem_NoSuccess(self): - """Test that __iter__() gets mocked in Dummy using getitem.""" - dummy = mox.MockObject(SubscribtableNonIterableClass) - # NOT doing dummy[index] + def testMockIter_ExpectedNoGetItem_NoSuccess(self): + """Test that __iter__() gets mocked in Dummy using getitem.""" + dummy = mox.MockObject(SubscribtableNonIterableClass) + # NOT doing dummy[index] - dummy._Replay() - function = lambda: [x for x in dummy] - self.assertRaises(mox.UnexpectedMethodCallError, function) + dummy._Replay() + function = lambda: [x for x in dummy] + self.assertRaises(mox.UnexpectedMethodCallError, function) - def testMockGetIter_WithSubClassOfNewStyleClass(self): - class NewStyleTestClass(object): - def __iter__(self): - return iter([1, 2, 3]) + def testMockGetIter_WithSubClassOfNewStyleClass(self): + class NewStyleTestClass(object): + def __iter__(self): + return iter([1, 2, 3]) - class TestSubClass(NewStyleTestClass): - pass + class TestSubClass(NewStyleTestClass): + pass - dummy = mox.MockObject(TestSubClass) - iter(dummy).AndReturn(iter(['a', 'b'])) - dummy._Replay() - self.assertEqual(['a', 'b'], [x for x in dummy]) - dummy._Verify() + dummy = mox.MockObject(TestSubClass) + iter(dummy).AndReturn(iter(['a', 'b'])) + dummy._Replay() + self.assertEqual(['a', 'b'], [x for x in dummy]) + dummy._Verify() - def testInstantiationWithAdditionalAttributes(self): - mock_object = mox.MockObject(TestClass, attrs={"attr1": "value"}) - self.assertEqual(mock_object.attr1, "value") + def testInstantiationWithAdditionalAttributes(self): + mock_object = mox.MockObject(TestClass, attrs={"attr1": "value"}) + self.assertEqual(mock_object.attr1, "value") - def testCantOverrideMethodsWithAttributes(self): - self.assertRaises(ValueError, mox.MockObject, TestClass, - attrs={"ValidCall": "value"}) + def testCantOverrideMethodsWithAttributes(self): + self.assertRaises(ValueError, mox.MockObject, TestClass, + attrs={"ValidCall": "value"}) - def testCantMockNonPublicAttributes(self): - self.assertRaises(mox.PrivateAttributeError, mox.MockObject, TestClass, - attrs={"_protected": "value"}) - self.assertRaises(mox.PrivateAttributeError, mox.MockObject, TestClass, - attrs={"__private": "value"}) + def testCantMockNonPublicAttributes(self): + self.assertRaises(mox.PrivateAttributeError, mox.MockObject, TestClass, + attrs={"_protected": "value"}) + self.assertRaises(mox.PrivateAttributeError, mox.MockObject, TestClass, + attrs={"__private": "value"}) class MoxTest(unittest.TestCase): - """Verify Mox works correctly.""" - - def setUp(self): - self.mox = mox.Mox() - - def testCreateObject(self): - """Mox should create a mock object.""" - mock_obj = self.mox.CreateMock(TestClass) - - def testVerifyObjectWithCompleteReplay(self): - """Mox should replay and verify all objects it created.""" - mock_obj = self.mox.CreateMock(TestClass) - mock_obj.ValidCall() - mock_obj.ValidCallWithArgs(mox.IsA(TestClass)) - self.mox.ReplayAll() - mock_obj.ValidCall() - mock_obj.ValidCallWithArgs(TestClass("some_value")) - self.mox.VerifyAll() - - def testVerifyObjectWithIncompleteReplay(self): - """Mox should raise an exception if a mock didn't replay completely.""" - mock_obj = self.mox.CreateMock(TestClass) - mock_obj.ValidCall() - self.mox.ReplayAll() - # ValidCall() is never made - self.assertRaises(mox.ExpectedMethodCallsError, self.mox.VerifyAll) - - def testEntireWorkflow(self): - """Test the whole work flow.""" - mock_obj = self.mox.CreateMock(TestClass) - mock_obj.ValidCall().AndReturn("yes") - self.mox.ReplayAll() - - ret_val = mock_obj.ValidCall() - self.assertEqual("yes", ret_val) - self.mox.VerifyAll() - - def testSignatureMatchingWithComparatorAsFirstArg(self): - """Test that the first argument can be a comparator.""" - - def VerifyLen(val): - """This will raise an exception when not given a list. - - This exception will be raised when trying to infer/validate the - method signature. - """ - return len(val) != 1 - - mock_obj = self.mox.CreateMock(TestClass) - # This intentionally does not name the 'nine' param so it triggers - # deeper inspection. - mock_obj.MethodWithArgs(mox.Func(VerifyLen), mox.IgnoreArg(), None) - self.mox.ReplayAll() - - mock_obj.MethodWithArgs([1, 2], "foo", None) - - self.mox.VerifyAll() - - def testCallableObject(self): - """Test recording calls to a callable object works.""" - mock_obj = self.mox.CreateMock(CallableClass) - mock_obj("foo").AndReturn("qux") - self.mox.ReplayAll() - - ret_val = mock_obj("foo") - self.assertEqual("qux", ret_val) - self.mox.VerifyAll() - - def testInheritedCallableObject(self): - """Test recording calls to an object inheriting from a callable object.""" - mock_obj = self.mox.CreateMock(InheritsFromCallable) - mock_obj("foo").AndReturn("qux") - self.mox.ReplayAll() - - ret_val = mock_obj("foo") - self.assertEqual("qux", ret_val) - self.mox.VerifyAll() - - def testCallOnNonCallableObject(self): - """Test that you cannot call a non-callable object.""" - mock_obj = self.mox.CreateMock("string is not callable") - self.assertRaises(TypeError, mock_obj) - - def testCallableObjectWithBadCall(self): - """Test verifying calls to a callable object works.""" - mock_obj = self.mox.CreateMock(CallableClass) - mock_obj("foo").AndReturn("qux") - self.mox.ReplayAll() - - self.assertRaises(mox.UnexpectedMethodCallError, mock_obj, "ZOOBAZ") - - def testCallableObjectVerifiesSignature(self): - mock_obj = self.mox.CreateMock(CallableClass) - # Too many arguments - self.assertRaises(AttributeError, mock_obj, "foo", "bar") - - def testUnorderedGroup(self): - """Test that using one unordered group works.""" - mock_obj = self.mox.CreateMockAnything() - mock_obj.Method(1).InAnyOrder() - mock_obj.Method(2).InAnyOrder() - self.mox.ReplayAll() - - mock_obj.Method(2) - mock_obj.Method(1) - - self.mox.VerifyAll() - - def testUnorderedGroupsInline(self): - """Unordered groups should work in the context of ordered calls.""" - mock_obj = self.mox.CreateMockAnything() - mock_obj.Open() - mock_obj.Method(1).InAnyOrder() - mock_obj.Method(2).InAnyOrder() - mock_obj.Close() - self.mox.ReplayAll() - - mock_obj.Open() - mock_obj.Method(2) - mock_obj.Method(1) - mock_obj.Close() - - self.mox.VerifyAll() - - def testMultipleUnorderdGroups(self): - """Multiple unoreded groups should work.""" - mock_obj = self.mox.CreateMockAnything() - mock_obj.Method(1).InAnyOrder() - mock_obj.Method(2).InAnyOrder() - mock_obj.Foo().InAnyOrder('group2') - mock_obj.Bar().InAnyOrder('group2') - self.mox.ReplayAll() - - mock_obj.Method(2) - mock_obj.Method(1) - mock_obj.Bar() - mock_obj.Foo() - - self.mox.VerifyAll() - - def testMultipleUnorderdGroupsOutOfOrder(self): - """Multiple unordered groups should maintain external order""" - mock_obj = self.mox.CreateMockAnything() - mock_obj.Method(1).InAnyOrder() - mock_obj.Method(2).InAnyOrder() - mock_obj.Foo().InAnyOrder('group2') - mock_obj.Bar().InAnyOrder('group2') - self.mox.ReplayAll() - - mock_obj.Method(2) - self.assertRaises(mox.UnexpectedMethodCallError, mock_obj.Bar) - - def testUnorderedGroupWithReturnValue(self): - """Unordered groups should work with return values.""" - mock_obj = self.mox.CreateMockAnything() - mock_obj.Open() - mock_obj.Method(1).InAnyOrder().AndReturn(9) - mock_obj.Method(2).InAnyOrder().AndReturn(10) - mock_obj.Close() - self.mox.ReplayAll() - - mock_obj.Open() - actual_two = mock_obj.Method(2) - actual_one = mock_obj.Method(1) - mock_obj.Close() - - self.assertEqual(9, actual_one) - self.assertEqual(10, actual_two) - - self.mox.VerifyAll() - - def testUnorderedGroupWithComparator(self): - """Unordered groups should work with comparators""" - - def VerifyOne(cmd): - if not isinstance(cmd, str): - self.fail('Unexpected type passed to comparator: ' + str(cmd)) - return cmd == 'test' - - def VerifyTwo(cmd): - return True - - mock_obj = self.mox.CreateMockAnything() - mock_obj.Foo(['test'], mox.Func(VerifyOne), bar=1).InAnyOrder().\ - AndReturn('yes test') - mock_obj.Foo(['test'], mox.Func(VerifyTwo), bar=1).InAnyOrder().\ - AndReturn('anything') - - self.mox.ReplayAll() - - mock_obj.Foo(['test'], 'anything', bar=1) - mock_obj.Foo(['test'], 'test', bar=1) - - self.mox.VerifyAll() - - def testMultipleTimes(self): - """Test if MultipleTimesGroup works.""" - mock_obj = self.mox.CreateMockAnything() - mock_obj.Method(1).MultipleTimes().AndReturn(9) - mock_obj.Method(2).AndReturn(10) - mock_obj.Method(3).MultipleTimes().AndReturn(42) - self.mox.ReplayAll() - - actual_one = mock_obj.Method(1) - second_one = mock_obj.Method(1) # This tests MultipleTimes. - actual_two = mock_obj.Method(2) - actual_three = mock_obj.Method(3) - mock_obj.Method(3) - mock_obj.Method(3) - - self.mox.VerifyAll() - - self.assertEqual(9, actual_one) - # Repeated calls should return same number. - self.assertEqual(9, second_one) - self.assertEqual(10, actual_two) - self.assertEqual(42, actual_three) - - def testMultipleTimesUsingIsAParameter(self): - """Test if MultipleTimesGroup works with a IsA parameter.""" - mock_obj = self.mox.CreateMockAnything() - mock_obj.Open() - mock_obj.Method(mox.IsA(str)).MultipleTimes("IsA").AndReturn(9) - mock_obj.Close() - self.mox.ReplayAll() - - mock_obj.Open() - actual_one = mock_obj.Method("1") - second_one = mock_obj.Method("2") # This tests MultipleTimes. - mock_obj.Close() - - self.mox.VerifyAll() - - self.assertEqual(9, actual_one) - # Repeated calls should return same number. - self.assertEqual(9, second_one) - - def testMutlipleTimesUsingFunc(self): - """Test that the Func is not evaluated more times than necessary. - - If a Func() has side effects, it can cause a passing test to fail. - """ - - self.counter = 0 - - def MyFunc(actual_str): - """Increment the counter if actual_str == 'foo'.""" - if actual_str == 'foo': - self.counter += 1 - return True - - mock_obj = self.mox.CreateMockAnything() - mock_obj.Open() - mock_obj.Method(mox.Func(MyFunc)).MultipleTimes() - mock_obj.Close() - self.mox.ReplayAll() - - mock_obj.Open() - mock_obj.Method('foo') - mock_obj.Method('foo') - mock_obj.Method('not-foo') - mock_obj.Close() - - self.mox.VerifyAll() - - self.assertEqual(2, self.counter) - - def testMultipleTimesThreeMethods(self): - """Test if MultipleTimesGroup works with three or more methods.""" - mock_obj = self.mox.CreateMockAnything() - mock_obj.Open() - mock_obj.Method(1).MultipleTimes().AndReturn(9) - mock_obj.Method(2).MultipleTimes().AndReturn(8) - mock_obj.Method(3).MultipleTimes().AndReturn(7) - mock_obj.Method(4).AndReturn(10) - mock_obj.Close() - self.mox.ReplayAll() - - mock_obj.Open() - actual_three = mock_obj.Method(3) - mock_obj.Method(1) - actual_two = mock_obj.Method(2) - mock_obj.Method(3) - actual_one = mock_obj.Method(1) - actual_four = mock_obj.Method(4) - mock_obj.Close() - - self.assertEqual(9, actual_one) - self.assertEqual(8, actual_two) - self.assertEqual(7, actual_three) - self.assertEqual(10, actual_four) - - self.mox.VerifyAll() - - def testMultipleTimesMissingOne(self): - """Test if MultipleTimesGroup fails if one method is missing.""" - mock_obj = self.mox.CreateMockAnything() - mock_obj.Open() - mock_obj.Method(1).MultipleTimes().AndReturn(9) - mock_obj.Method(2).MultipleTimes().AndReturn(8) - mock_obj.Method(3).MultipleTimes().AndReturn(7) - mock_obj.Method(4).AndReturn(10) - mock_obj.Close() - self.mox.ReplayAll() - - mock_obj.Open() - mock_obj.Method(3) - mock_obj.Method(2) - mock_obj.Method(3) - mock_obj.Method(3) - mock_obj.Method(2) - - self.assertRaises(mox.UnexpectedMethodCallError, mock_obj.Method, 4) - - def testMultipleTimesTwoGroups(self): - """Test if MultipleTimesGroup works with a group after a - MultipleTimesGroup. - """ - mock_obj = self.mox.CreateMockAnything() - mock_obj.Open() - mock_obj.Method(1).MultipleTimes().AndReturn(9) - mock_obj.Method(3).MultipleTimes("nr2").AndReturn(42) - mock_obj.Close() - self.mox.ReplayAll() - - mock_obj.Open() - actual_one = mock_obj.Method(1) - mock_obj.Method(1) - actual_three = mock_obj.Method(3) - mock_obj.Method(3) - mock_obj.Close() - - self.assertEqual(9, actual_one) - self.assertEqual(42, actual_three) - - self.mox.VerifyAll() - - def testMultipleTimesTwoGroupsFailure(self): - """Test if MultipleTimesGroup fails with a group after a - MultipleTimesGroup. - """ - mock_obj = self.mox.CreateMockAnything() - mock_obj.Open() - mock_obj.Method(1).MultipleTimes().AndReturn(9) - mock_obj.Method(3).MultipleTimes("nr2").AndReturn(42) - mock_obj.Close() - self.mox.ReplayAll() - - mock_obj.Open() - actual_one = mock_obj.Method(1) - mock_obj.Method(1) - actual_three = mock_obj.Method(3) - - self.assertRaises(mox.UnexpectedMethodCallError, mock_obj.Method, 1) - - def testWithSideEffects(self): - """Test side effect operations actually modify their target objects.""" - def modifier(mutable_list): - mutable_list[0] = 'mutated' - mock_obj = self.mox.CreateMockAnything() - mock_obj.ConfigureInOutParameter(['original']).WithSideEffects(modifier) - mock_obj.WorkWithParameter(['mutated']) - self.mox.ReplayAll() - - local_list = ['original'] - mock_obj.ConfigureInOutParameter(local_list) - mock_obj.WorkWithParameter(local_list) - - self.mox.VerifyAll() - - def testWithSideEffectsException(self): - """Test side effect operations actually modify their target objects.""" - def modifier(mutable_list): - mutable_list[0] = 'mutated' - mock_obj = self.mox.CreateMockAnything() - method = mock_obj.ConfigureInOutParameter(['original']) - method.WithSideEffects(modifier).AndRaise(Exception('exception')) - mock_obj.WorkWithParameter(['mutated']) - self.mox.ReplayAll() - - local_list = ['original'] - self.assertRaises(Exception, - mock_obj.ConfigureInOutParameter, - local_list) - mock_obj.WorkWithParameter(local_list) - - self.mox.VerifyAll() - - def testStubOutMethod(self): - """Test that a method is replaced with a MockObject.""" - test_obj = TestClass() - method_type = type(test_obj.OtherValidCall) - # Replace OtherValidCall with a mock. - self.mox.StubOutWithMock(test_obj, 'OtherValidCall') - self.assertTrue(isinstance(test_obj.OtherValidCall, mox.MockObject)) - self.assertFalse(type(test_obj.OtherValidCall) is method_type) - - test_obj.OtherValidCall().AndReturn('foo') - self.mox.ReplayAll() - - actual = test_obj.OtherValidCall() - - self.mox.VerifyAll() - self.mox.UnsetStubs() - self.assertEqual('foo', actual) - self.assertTrue(type(test_obj.OtherValidCall) is method_type) - - def testStubOutMethod_Unbound_Comparator(self): - instance = TestClass() - self.mox.StubOutWithMock(TestClass, 'OtherValidCall') - - TestClass.OtherValidCall(mox.IgnoreArg()).AndReturn('foo') - self.mox.ReplayAll() - - actual = TestClass.OtherValidCall(instance) - - self.mox.VerifyAll() - self.mox.UnsetStubs() - self.assertEqual('foo', actual) - - def testStubOutMethod_Unbound_Subclass_Comparator(self): - self.mox.StubOutWithMock( - mox_helper.TestClassFromAnotherModule, 'Value') - mox_helper.TestClassFromAnotherModule.Value( - mox.IsA(mox_helper.ChildClassFromAnotherModule)).AndReturn('foo') - self.mox.ReplayAll() - - instance = mox_helper.ChildClassFromAnotherModule() - actual = mox_helper.TestClassFromAnotherModule.Value(instance) - - self.mox.VerifyAll() - self.mox.UnsetStubs() - self.assertEqual('foo', actual) - - def testStubOuMethod_Unbound_WithOptionalParams(self): - self.mox = mox.Mox() - self.mox.StubOutWithMock(TestClass, 'OptionalArgs') - TestClass.OptionalArgs(mox.IgnoreArg(), foo=2) - self.mox.ReplayAll() - - t = TestClass() - TestClass.OptionalArgs(t, foo=2) - - self.mox.VerifyAll() - self.mox.UnsetStubs() + """Verify Mox works correctly.""" + + def setUp(self): + self.mox = mox.Mox() + + def testCreateObject(self): + """Mox should create a mock object.""" + mock_obj = self.mox.CreateMock(TestClass) + + def testVerifyObjectWithCompleteReplay(self): + """Mox should replay and verify all objects it created.""" + mock_obj = self.mox.CreateMock(TestClass) + mock_obj.ValidCall() + mock_obj.ValidCallWithArgs(mox.IsA(TestClass)) + self.mox.ReplayAll() + mock_obj.ValidCall() + mock_obj.ValidCallWithArgs(TestClass("some_value")) + self.mox.VerifyAll() + + def testVerifyObjectWithIncompleteReplay(self): + """Mox should raise an exception if a mock didn't replay completely.""" + mock_obj = self.mox.CreateMock(TestClass) + mock_obj.ValidCall() + self.mox.ReplayAll() + # ValidCall() is never made + self.assertRaises(mox.ExpectedMethodCallsError, self.mox.VerifyAll) + + def testEntireWorkflow(self): + """Test the whole work flow.""" + mock_obj = self.mox.CreateMock(TestClass) + mock_obj.ValidCall().AndReturn("yes") + self.mox.ReplayAll() + + ret_val = mock_obj.ValidCall() + self.assertEqual("yes", ret_val) + self.mox.VerifyAll() + + def testSignatureMatchingWithComparatorAsFirstArg(self): + """Test that the first argument can be a comparator.""" + + def VerifyLen(val): + """This will raise an exception when not given a list. + + This exception will be raised when trying to infer/validate the + method signature. + """ + return len(val) != 1 + + mock_obj = self.mox.CreateMock(TestClass) + # This intentionally does not name the 'nine' param so it triggers + # deeper inspection. + mock_obj.MethodWithArgs(mox.Func(VerifyLen), mox.IgnoreArg(), None) + self.mox.ReplayAll() + + mock_obj.MethodWithArgs([1, 2], "foo", None) + + self.mox.VerifyAll() + + def testCallableObject(self): + """Test recording calls to a callable object works.""" + mock_obj = self.mox.CreateMock(CallableClass) + mock_obj("foo").AndReturn("qux") + self.mox.ReplayAll() + + ret_val = mock_obj("foo") + self.assertEqual("qux", ret_val) + self.mox.VerifyAll() + + def testInheritedCallableObject(self): + """Test recording calls to an object inheriting from a callable object.""" + mock_obj = self.mox.CreateMock(InheritsFromCallable) + mock_obj("foo").AndReturn("qux") + self.mox.ReplayAll() + + ret_val = mock_obj("foo") + self.assertEqual("qux", ret_val) + self.mox.VerifyAll() + + def testCallOnNonCallableObject(self): + """Test that you cannot call a non-callable object.""" + mock_obj = self.mox.CreateMock("string is not callable") + self.assertRaises(TypeError, mock_obj) + + def testCallableObjectWithBadCall(self): + """Test verifying calls to a callable object works.""" + mock_obj = self.mox.CreateMock(CallableClass) + mock_obj("foo").AndReturn("qux") + self.mox.ReplayAll() + + self.assertRaises(mox.UnexpectedMethodCallError, mock_obj, "ZOOBAZ") + + def testCallableObjectVerifiesSignature(self): + mock_obj = self.mox.CreateMock(CallableClass) + # Too many arguments + self.assertRaises(AttributeError, mock_obj, "foo", "bar") + + def testUnorderedGroup(self): + """Test that using one unordered group works.""" + mock_obj = self.mox.CreateMockAnything() + mock_obj.Method(1).InAnyOrder() + mock_obj.Method(2).InAnyOrder() + self.mox.ReplayAll() + + mock_obj.Method(2) + mock_obj.Method(1) + + self.mox.VerifyAll() + + def testUnorderedGroupsInline(self): + """Unordered groups should work in the context of ordered calls.""" + mock_obj = self.mox.CreateMockAnything() + mock_obj.Open() + mock_obj.Method(1).InAnyOrder() + mock_obj.Method(2).InAnyOrder() + mock_obj.Close() + self.mox.ReplayAll() + + mock_obj.Open() + mock_obj.Method(2) + mock_obj.Method(1) + mock_obj.Close() + + self.mox.VerifyAll() + + def testMultipleUnorderdGroups(self): + """Multiple unoreded groups should work.""" + mock_obj = self.mox.CreateMockAnything() + mock_obj.Method(1).InAnyOrder() + mock_obj.Method(2).InAnyOrder() + mock_obj.Foo().InAnyOrder('group2') + mock_obj.Bar().InAnyOrder('group2') + self.mox.ReplayAll() + + mock_obj.Method(2) + mock_obj.Method(1) + mock_obj.Bar() + mock_obj.Foo() + + self.mox.VerifyAll() + + def testMultipleUnorderdGroupsOutOfOrder(self): + """Multiple unordered groups should maintain external order""" + mock_obj = self.mox.CreateMockAnything() + mock_obj.Method(1).InAnyOrder() + mock_obj.Method(2).InAnyOrder() + mock_obj.Foo().InAnyOrder('group2') + mock_obj.Bar().InAnyOrder('group2') + self.mox.ReplayAll() + + mock_obj.Method(2) + self.assertRaises(mox.UnexpectedMethodCallError, mock_obj.Bar) + + def testUnorderedGroupWithReturnValue(self): + """Unordered groups should work with return values.""" + mock_obj = self.mox.CreateMockAnything() + mock_obj.Open() + mock_obj.Method(1).InAnyOrder().AndReturn(9) + mock_obj.Method(2).InAnyOrder().AndReturn(10) + mock_obj.Close() + self.mox.ReplayAll() + + mock_obj.Open() + actual_two = mock_obj.Method(2) + actual_one = mock_obj.Method(1) + mock_obj.Close() + + self.assertEqual(9, actual_one) + self.assertEqual(10, actual_two) + + self.mox.VerifyAll() + + def testUnorderedGroupWithComparator(self): + """Unordered groups should work with comparators""" + + def VerifyOne(cmd): + if not isinstance(cmd, str): + self.fail('Unexpected type passed to comparator: ' + str(cmd)) + return cmd == 'test' + + def VerifyTwo(cmd): + return True + + mock_obj = self.mox.CreateMockAnything() + mock_obj.Foo(['test'], mox.Func(VerifyOne), bar=1).InAnyOrder().\ + AndReturn('yes test') + mock_obj.Foo(['test'], mox.Func(VerifyTwo), bar=1).InAnyOrder().\ + AndReturn('anything') + + self.mox.ReplayAll() + + mock_obj.Foo(['test'], 'anything', bar=1) + mock_obj.Foo(['test'], 'test', bar=1) + + self.mox.VerifyAll() + + def testMultipleTimes(self): + """Test if MultipleTimesGroup works.""" + mock_obj = self.mox.CreateMockAnything() + mock_obj.Method(1).MultipleTimes().AndReturn(9) + mock_obj.Method(2).AndReturn(10) + mock_obj.Method(3).MultipleTimes().AndReturn(42) + self.mox.ReplayAll() + + actual_one = mock_obj.Method(1) + second_one = mock_obj.Method(1) # This tests MultipleTimes. + actual_two = mock_obj.Method(2) + actual_three = mock_obj.Method(3) + mock_obj.Method(3) + mock_obj.Method(3) + + self.mox.VerifyAll() + + self.assertEqual(9, actual_one) + # Repeated calls should return same number. + self.assertEqual(9, second_one) + self.assertEqual(10, actual_two) + self.assertEqual(42, actual_three) + + def testMultipleTimesUsingIsAParameter(self): + """Test if MultipleTimesGroup works with a IsA parameter.""" + mock_obj = self.mox.CreateMockAnything() + mock_obj.Open() + mock_obj.Method(mox.IsA(str)).MultipleTimes("IsA").AndReturn(9) + mock_obj.Close() + self.mox.ReplayAll() + + mock_obj.Open() + actual_one = mock_obj.Method("1") + second_one = mock_obj.Method("2") # This tests MultipleTimes. + mock_obj.Close() + + self.mox.VerifyAll() + + self.assertEqual(9, actual_one) + # Repeated calls should return same number. + self.assertEqual(9, second_one) + + def testMutlipleTimesUsingFunc(self): + """Test that the Func is not evaluated more times than necessary. + + If a Func() has side effects, it can cause a passing test to fail. + """ + + self.counter = 0 + + def MyFunc(actual_str): + """Increment the counter if actual_str == 'foo'.""" + if actual_str == 'foo': + self.counter += 1 + return True + + mock_obj = self.mox.CreateMockAnything() + mock_obj.Open() + mock_obj.Method(mox.Func(MyFunc)).MultipleTimes() + mock_obj.Close() + self.mox.ReplayAll() + + mock_obj.Open() + mock_obj.Method('foo') + mock_obj.Method('foo') + mock_obj.Method('not-foo') + mock_obj.Close() + + self.mox.VerifyAll() + + self.assertEqual(2, self.counter) + + def testMultipleTimesThreeMethods(self): + """Test if MultipleTimesGroup works with three or more methods.""" + mock_obj = self.mox.CreateMockAnything() + mock_obj.Open() + mock_obj.Method(1).MultipleTimes().AndReturn(9) + mock_obj.Method(2).MultipleTimes().AndReturn(8) + mock_obj.Method(3).MultipleTimes().AndReturn(7) + mock_obj.Method(4).AndReturn(10) + mock_obj.Close() + self.mox.ReplayAll() + + mock_obj.Open() + actual_three = mock_obj.Method(3) + mock_obj.Method(1) + actual_two = mock_obj.Method(2) + mock_obj.Method(3) + actual_one = mock_obj.Method(1) + actual_four = mock_obj.Method(4) + mock_obj.Close() + + self.assertEqual(9, actual_one) + self.assertEqual(8, actual_two) + self.assertEqual(7, actual_three) + self.assertEqual(10, actual_four) + + self.mox.VerifyAll() + + def testMultipleTimesMissingOne(self): + """Test if MultipleTimesGroup fails if one method is missing.""" + mock_obj = self.mox.CreateMockAnything() + mock_obj.Open() + mock_obj.Method(1).MultipleTimes().AndReturn(9) + mock_obj.Method(2).MultipleTimes().AndReturn(8) + mock_obj.Method(3).MultipleTimes().AndReturn(7) + mock_obj.Method(4).AndReturn(10) + mock_obj.Close() + self.mox.ReplayAll() + + mock_obj.Open() + mock_obj.Method(3) + mock_obj.Method(2) + mock_obj.Method(3) + mock_obj.Method(3) + mock_obj.Method(2) + + self.assertRaises(mox.UnexpectedMethodCallError, mock_obj.Method, 4) + + def testMultipleTimesTwoGroups(self): + """Test if MultipleTimesGroup works with a group after a + MultipleTimesGroup. + """ + mock_obj = self.mox.CreateMockAnything() + mock_obj.Open() + mock_obj.Method(1).MultipleTimes().AndReturn(9) + mock_obj.Method(3).MultipleTimes("nr2").AndReturn(42) + mock_obj.Close() + self.mox.ReplayAll() + + mock_obj.Open() + actual_one = mock_obj.Method(1) + mock_obj.Method(1) + actual_three = mock_obj.Method(3) + mock_obj.Method(3) + mock_obj.Close() + + self.assertEqual(9, actual_one) + self.assertEqual(42, actual_three) + + self.mox.VerifyAll() + + def testMultipleTimesTwoGroupsFailure(self): + """Test if MultipleTimesGroup fails with a group after a + MultipleTimesGroup. + """ + mock_obj = self.mox.CreateMockAnything() + mock_obj.Open() + mock_obj.Method(1).MultipleTimes().AndReturn(9) + mock_obj.Method(3).MultipleTimes("nr2").AndReturn(42) + mock_obj.Close() + self.mox.ReplayAll() + + mock_obj.Open() + actual_one = mock_obj.Method(1) + mock_obj.Method(1) + actual_three = mock_obj.Method(3) + + self.assertRaises(mox.UnexpectedMethodCallError, mock_obj.Method, 1) + + def testWithSideEffects(self): + """Test side effect operations actually modify their target objects.""" + def modifier(mutable_list): + mutable_list[0] = 'mutated' + mock_obj = self.mox.CreateMockAnything() + mock_obj.ConfigureInOutParameter(['original']).WithSideEffects(modifier) + mock_obj.WorkWithParameter(['mutated']) + self.mox.ReplayAll() + + local_list = ['original'] + mock_obj.ConfigureInOutParameter(local_list) + mock_obj.WorkWithParameter(local_list) + + self.mox.VerifyAll() + + def testWithSideEffectsException(self): + """Test side effect operations actually modify their target objects.""" + def modifier(mutable_list): + mutable_list[0] = 'mutated' + mock_obj = self.mox.CreateMockAnything() + method = mock_obj.ConfigureInOutParameter(['original']) + method.WithSideEffects(modifier).AndRaise(Exception('exception')) + mock_obj.WorkWithParameter(['mutated']) + self.mox.ReplayAll() + + local_list = ['original'] + self.assertRaises(Exception, + mock_obj.ConfigureInOutParameter, + local_list) + mock_obj.WorkWithParameter(local_list) + + self.mox.VerifyAll() + + def testStubOutMethod(self): + """Test that a method is replaced with a MockObject.""" + test_obj = TestClass() + method_type = type(test_obj.OtherValidCall) + # Replace OtherValidCall with a mock. + self.mox.StubOutWithMock(test_obj, 'OtherValidCall') + self.assertTrue(isinstance(test_obj.OtherValidCall, mox.MockObject)) + self.assertFalse(type(test_obj.OtherValidCall) is method_type) + + test_obj.OtherValidCall().AndReturn('foo') + self.mox.ReplayAll() + + actual = test_obj.OtherValidCall() + + self.mox.VerifyAll() + self.mox.UnsetStubs() + self.assertEqual('foo', actual) + self.assertTrue(type(test_obj.OtherValidCall) is method_type) + + def testStubOutMethod_Unbound_Comparator(self): + instance = TestClass() + self.mox.StubOutWithMock(TestClass, 'OtherValidCall') + + TestClass.OtherValidCall(mox.IgnoreArg()).AndReturn('foo') + self.mox.ReplayAll() + + actual = TestClass.OtherValidCall(instance) + + self.mox.VerifyAll() + self.mox.UnsetStubs() + self.assertEqual('foo', actual) + + def testStubOutMethod_Unbound_Subclass_Comparator(self): + self.mox.StubOutWithMock( + mox_helper.TestClassFromAnotherModule, 'Value') + mox_helper.TestClassFromAnotherModule.Value( + mox.IsA(mox_helper.ChildClassFromAnotherModule)).AndReturn('foo') + self.mox.ReplayAll() + + instance = mox_helper.ChildClassFromAnotherModule() + actual = mox_helper.TestClassFromAnotherModule.Value(instance) + + self.mox.VerifyAll() + self.mox.UnsetStubs() + self.assertEqual('foo', actual) + + def testStubOuMethod_Unbound_WithOptionalParams(self): + self.mox = mox.Mox() + self.mox.StubOutWithMock(TestClass, 'OptionalArgs') + TestClass.OptionalArgs(mox.IgnoreArg(), foo=2) + self.mox.ReplayAll() + + t = TestClass() + TestClass.OptionalArgs(t, foo=2) + + self.mox.VerifyAll() + self.mox.UnsetStubs() - def testStubOutMethod_Unbound_ActualInstance(self): - instance = TestClass() - self.mox.StubOutWithMock(TestClass, 'OtherValidCall') + def testStubOutMethod_Unbound_ActualInstance(self): + instance = TestClass() + self.mox.StubOutWithMock(TestClass, 'OtherValidCall') - TestClass.OtherValidCall(instance).AndReturn('foo') - self.mox.ReplayAll() + TestClass.OtherValidCall(instance).AndReturn('foo') + self.mox.ReplayAll() - actual = TestClass.OtherValidCall(instance) + actual = TestClass.OtherValidCall(instance) - self.mox.VerifyAll() - self.mox.UnsetStubs() - self.assertEqual('foo', actual) + self.mox.VerifyAll() + self.mox.UnsetStubs() + self.assertEqual('foo', actual) - def testStubOutMethod_Unbound_DifferentInstance(self): - instance = TestClass() - self.mox.StubOutWithMock(TestClass, 'OtherValidCall') + def testStubOutMethod_Unbound_DifferentInstance(self): + instance = TestClass() + self.mox.StubOutWithMock(TestClass, 'OtherValidCall') - TestClass.OtherValidCall(instance).AndReturn('foo') - self.mox.ReplayAll() + TestClass.OtherValidCall(instance).AndReturn('foo') + self.mox.ReplayAll() - # This should fail, since the instances are different - self.assertRaises(mox.UnexpectedMethodCallError, - TestClass.OtherValidCall, "wrong self") + # This should fail, since the instances are different + self.assertRaises(mox.UnexpectedMethodCallError, + TestClass.OtherValidCall, "wrong self") - self.mox.VerifyAll() - self.mox.UnsetStubs() - - def testStubOutMethod_Unbound_NamedUsingPositional(self): - """Check positional parameters can be matched to keyword arguments.""" - self.mox.StubOutWithMock(mox_helper.ExampleClass, 'NamedParams') - instance = mox_helper.ExampleClass() - mox_helper.ExampleClass.NamedParams(instance, 'foo', baz=None) - self.mox.ReplayAll() + self.mox.VerifyAll() + self.mox.UnsetStubs() + + def testStubOutMethod_Unbound_NamedUsingPositional(self): + """Check positional parameters can be matched to keyword arguments.""" + self.mox.StubOutWithMock(mox_helper.ExampleClass, 'NamedParams') + instance = mox_helper.ExampleClass() + mox_helper.ExampleClass.NamedParams(instance, 'foo', baz=None) + self.mox.ReplayAll() - mox_helper.ExampleClass.NamedParams(instance, 'foo', baz=None) + mox_helper.ExampleClass.NamedParams(instance, 'foo', baz=None) - self.mox.VerifyAll() - self.mox.UnsetStubs() + self.mox.VerifyAll() + self.mox.UnsetStubs() - def testStubOutMethod_Unbound_NamedUsingPositional_SomePositional(self): - """Check positional parameters can be matched to keyword arguments.""" - self.mox.StubOutWithMock(mox_helper.ExampleClass, 'TestMethod') - instance = mox_helper.ExampleClass() - mox_helper.ExampleClass.TestMethod(instance, 'one', 'two', 'nine') - self.mox.ReplayAll() + def testStubOutMethod_Unbound_NamedUsingPositional_SomePositional(self): + """Check positional parameters can be matched to keyword arguments.""" + self.mox.StubOutWithMock(mox_helper.ExampleClass, 'TestMethod') + instance = mox_helper.ExampleClass() + mox_helper.ExampleClass.TestMethod(instance, 'one', 'two', 'nine') + self.mox.ReplayAll() - mox_helper.ExampleClass.TestMethod(instance, 'one', 'two', 'nine') + mox_helper.ExampleClass.TestMethod(instance, 'one', 'two', 'nine') - self.mox.VerifyAll() - self.mox.UnsetStubs() + self.mox.VerifyAll() + self.mox.UnsetStubs() - def testStubOutMethod_Unbound_SpecialArgs(self): - self.mox.StubOutWithMock(mox_helper.ExampleClass, 'SpecialArgs') - instance = mox_helper.ExampleClass() - mox_helper.ExampleClass.SpecialArgs(instance, 'foo', None, bar='bar') - self.mox.ReplayAll() + def testStubOutMethod_Unbound_SpecialArgs(self): + self.mox.StubOutWithMock(mox_helper.ExampleClass, 'SpecialArgs') + instance = mox_helper.ExampleClass() + mox_helper.ExampleClass.SpecialArgs(instance, 'foo', None, bar='bar') + self.mox.ReplayAll() - mox_helper.ExampleClass.SpecialArgs(instance, 'foo', None, bar='bar') + mox_helper.ExampleClass.SpecialArgs(instance, 'foo', None, bar='bar') - self.mox.VerifyAll() - self.mox.UnsetStubs() + self.mox.VerifyAll() + self.mox.UnsetStubs() - def testStubOutMethod_Bound_SimpleTest(self): - t = self.mox.CreateMock(TestClass) + def testStubOutMethod_Bound_SimpleTest(self): + t = self.mox.CreateMock(TestClass) - t.MethodWithArgs(mox.IgnoreArg(), mox.IgnoreArg()).AndReturn('foo') - self.mox.ReplayAll() + t.MethodWithArgs(mox.IgnoreArg(), mox.IgnoreArg()).AndReturn('foo') + self.mox.ReplayAll() - actual = t.MethodWithArgs(None, None) + actual = t.MethodWithArgs(None, None) - self.mox.VerifyAll() - self.mox.UnsetStubs() - self.assertEqual('foo', actual) + self.mox.VerifyAll() + self.mox.UnsetStubs() + self.assertEqual('foo', actual) - def testStubOutMethod_Bound_NamedUsingPositional(self): - """Check positional parameters can be matched to keyword arguments.""" - self.mox.StubOutWithMock(mox_helper.ExampleClass, 'NamedParams') - instance = mox_helper.ExampleClass() - instance.NamedParams('foo', baz=None) - self.mox.ReplayAll() + def testStubOutMethod_Bound_NamedUsingPositional(self): + """Check positional parameters can be matched to keyword arguments.""" + self.mox.StubOutWithMock(mox_helper.ExampleClass, 'NamedParams') + instance = mox_helper.ExampleClass() + instance.NamedParams('foo', baz=None) + self.mox.ReplayAll() - instance.NamedParams('foo', baz=None) + instance.NamedParams('foo', baz=None) - self.mox.VerifyAll() - self.mox.UnsetStubs() + self.mox.VerifyAll() + self.mox.UnsetStubs() - def testStubOutMethod_Bound_NamedUsingPositional_SomePositional(self): - """Check positional parameters can be matched to keyword arguments.""" - self.mox.StubOutWithMock(mox_helper.ExampleClass, 'TestMethod') - instance = mox_helper.ExampleClass() - instance.TestMethod(instance, 'one', 'two', 'nine') - self.mox.ReplayAll() + def testStubOutMethod_Bound_NamedUsingPositional_SomePositional(self): + """Check positional parameters can be matched to keyword arguments.""" + self.mox.StubOutWithMock(mox_helper.ExampleClass, 'TestMethod') + instance = mox_helper.ExampleClass() + instance.TestMethod(instance, 'one', 'two', 'nine') + self.mox.ReplayAll() - instance.TestMethod(instance, 'one', 'two', 'nine') + instance.TestMethod(instance, 'one', 'two', 'nine') - self.mox.VerifyAll() - self.mox.UnsetStubs() + self.mox.VerifyAll() + self.mox.UnsetStubs() - def testStubOutMethod_Bound_SpecialArgs(self): - self.mox.StubOutWithMock(mox_helper.ExampleClass, 'SpecialArgs') - instance = mox_helper.ExampleClass() - instance.SpecialArgs(instance, 'foo', None, bar='bar') - self.mox.ReplayAll() + def testStubOutMethod_Bound_SpecialArgs(self): + self.mox.StubOutWithMock(mox_helper.ExampleClass, 'SpecialArgs') + instance = mox_helper.ExampleClass() + instance.SpecialArgs(instance, 'foo', None, bar='bar') + self.mox.ReplayAll() - instance.SpecialArgs(instance, 'foo', None, bar='bar') + instance.SpecialArgs(instance, 'foo', None, bar='bar') - self.mox.VerifyAll() - self.mox.UnsetStubs() + self.mox.VerifyAll() + self.mox.UnsetStubs() - def testStubOutMethod_Func_PropgatesExceptions(self): - """Errors in a Func comparator should propagate to the calling method.""" - class TestException(Exception): - pass + def testStubOutMethod_Func_PropgatesExceptions(self): + """Errors in a Func comparator should propagate to the calling method.""" + class TestException(Exception): + pass - def raiseExceptionOnNotOne(value): - if value == 1: - return True - else: - raise TestException + def raiseExceptionOnNotOne(value): + if value == 1: + return True + else: + raise TestException - test_obj = TestClass() - self.mox.StubOutWithMock(test_obj, 'MethodWithArgs') - test_obj.MethodWithArgs( - mox.IgnoreArg(), mox.Func(raiseExceptionOnNotOne)).AndReturn(1) - test_obj.MethodWithArgs( - mox.IgnoreArg(), mox.Func(raiseExceptionOnNotOne)).AndReturn(1) - self.mox.ReplayAll() + test_obj = TestClass() + self.mox.StubOutWithMock(test_obj, 'MethodWithArgs') + test_obj.MethodWithArgs( + mox.IgnoreArg(), mox.Func(raiseExceptionOnNotOne)).AndReturn(1) + test_obj.MethodWithArgs( + mox.IgnoreArg(), mox.Func(raiseExceptionOnNotOne)).AndReturn(1) + self.mox.ReplayAll() - self.assertEqual(test_obj.MethodWithArgs('ignored', 1), 1) - self.assertRaises(TestException, - test_obj.MethodWithArgs, 'ignored', 2) + self.assertEqual(test_obj.MethodWithArgs('ignored', 1), 1) + self.assertRaises(TestException, + test_obj.MethodWithArgs, 'ignored', 2) - self.mox.VerifyAll() - self.mox.UnsetStubs() + self.mox.VerifyAll() + self.mox.UnsetStubs() - def testStubOut_SignatureMatching_init_(self): - self.mox.StubOutWithMock(mox_helper.ExampleClass, '__init__') - mox_helper.ExampleClass.__init__(mox.IgnoreArg()) - self.mox.ReplayAll() + def testStubOut_SignatureMatching_init_(self): + self.mox.StubOutWithMock(mox_helper.ExampleClass, '__init__') + mox_helper.ExampleClass.__init__(mox.IgnoreArg()) + self.mox.ReplayAll() - # Create an instance of a child class, which calls the parent - # __init__ - mox_helper.ChildExampleClass() + # Create an instance of a child class, which calls the parent + # __init__ + mox_helper.ChildExampleClass() - self.mox.VerifyAll() - self.mox.UnsetStubs() + self.mox.VerifyAll() + self.mox.UnsetStubs() - def testStubOutClass_OldStyle(self): - """Test a mocked class whose __init__ returns a Mock.""" - self.mox.StubOutWithMock(mox_helper, 'TestClassFromAnotherModule') - self.assertTrue(isinstance(mox_helper.TestClassFromAnotherModule, - mox.MockObject)) + def testStubOutClass_OldStyle(self): + """Test a mocked class whose __init__ returns a Mock.""" + self.mox.StubOutWithMock(mox_helper, 'TestClassFromAnotherModule') + self.assertTrue(isinstance(mox_helper.TestClassFromAnotherModule, + mox.MockObject)) - mock_instance = self.mox.CreateMock( - mox_helper.TestClassFromAnotherModule) - mox_helper.TestClassFromAnotherModule().AndReturn(mock_instance) - mock_instance.Value().AndReturn('mock instance') + mock_instance = self.mox.CreateMock( + mox_helper.TestClassFromAnotherModule) + mox_helper.TestClassFromAnotherModule().AndReturn(mock_instance) + mock_instance.Value().AndReturn('mock instance') - self.mox.ReplayAll() + self.mox.ReplayAll() - a_mock = mox_helper.TestClassFromAnotherModule() - actual = a_mock.Value() + a_mock = mox_helper.TestClassFromAnotherModule() + actual = a_mock.Value() - self.mox.VerifyAll() - self.mox.UnsetStubs() - self.assertEqual('mock instance', actual) + self.mox.VerifyAll() + self.mox.UnsetStubs() + self.assertEqual('mock instance', actual) - def testStubOutClass(self): - self.mox.StubOutClassWithMocks(mox_helper, 'CallableClass') + def testStubOutClass(self): + self.mox.StubOutClassWithMocks(mox_helper, 'CallableClass') - # Instance one - mock_one = mox_helper.CallableClass(1, 2) - mock_one.Value().AndReturn('mock') + # Instance one + mock_one = mox_helper.CallableClass(1, 2) + mock_one.Value().AndReturn('mock') - # Instance two - mock_two = mox_helper.CallableClass(8, 9) - mock_two('one').AndReturn('called mock') + # Instance two + mock_two = mox_helper.CallableClass(8, 9) + mock_two('one').AndReturn('called mock') - self.mox.ReplayAll() + self.mox.ReplayAll() - one = mox_helper.CallableClass(1, 2) - actual_one = one.Value() + one = mox_helper.CallableClass(1, 2) + actual_one = one.Value() - two = mox_helper.CallableClass(8, 9) - actual_two = two('one') + two = mox_helper.CallableClass(8, 9) + actual_two = two('one') - self.mox.VerifyAll() - self.mox.UnsetStubs() + self.mox.VerifyAll() + self.mox.UnsetStubs() - # Verify the correct mocks were returned - self.assertEqual(mock_one, one) - self.assertEqual(mock_two, two) + # Verify the correct mocks were returned + self.assertEqual(mock_one, one) + self.assertEqual(mock_two, two) - # Verify - self.assertEqual('mock', actual_one) - self.assertEqual('called mock', actual_two) + # Verify + self.assertEqual('mock', actual_one) + self.assertEqual('called mock', actual_two) - def testStubOutClass_NotAClass(self): - self.assertRaises(TypeError, self.mox.StubOutClassWithMocks, - mox_helper, 'MyTestFunction') + def testStubOutClass_NotAClass(self): + self.assertRaises(TypeError, self.mox.StubOutClassWithMocks, + mox_helper, 'MyTestFunction') - def testStubOutClassNotEnoughCreated(self): - self.mox.StubOutClassWithMocks(mox_helper, 'CallableClass') + def testStubOutClassNotEnoughCreated(self): + self.mox.StubOutClassWithMocks(mox_helper, 'CallableClass') - mox_helper.CallableClass(1, 2) - mox_helper.CallableClass(8, 9) + mox_helper.CallableClass(1, 2) + mox_helper.CallableClass(8, 9) - self.mox.ReplayAll() - mox_helper.CallableClass(1, 2) - - self.assertRaises(mox.ExpectedMockCreationError, self.mox.VerifyAll) - self.mox.UnsetStubs() - - def testStubOutClassWrongSignature(self): - self.mox.StubOutClassWithMocks(mox_helper, 'CallableClass') - - self.assertRaises(AttributeError, mox_helper.CallableClass) + self.mox.ReplayAll() + mox_helper.CallableClass(1, 2) + + self.assertRaises(mox.ExpectedMockCreationError, self.mox.VerifyAll) + self.mox.UnsetStubs() + + def testStubOutClassWrongSignature(self): + self.mox.StubOutClassWithMocks(mox_helper, 'CallableClass') + + self.assertRaises(AttributeError, mox_helper.CallableClass) - self.mox.UnsetStubs() + self.mox.UnsetStubs() - def testStubOutClassWrongParameters(self): - self.mox.StubOutClassWithMocks(mox_helper, 'CallableClass') + def testStubOutClassWrongParameters(self): + self.mox.StubOutClassWithMocks(mox_helper, 'CallableClass') - mox_helper.CallableClass(1, 2) + mox_helper.CallableClass(1, 2) - self.mox.ReplayAll() + self.mox.ReplayAll() - self.assertRaises(mox.UnexpectedMethodCallError, - mox_helper.CallableClass, 8, 9) - self.mox.UnsetStubs() + self.assertRaises(mox.UnexpectedMethodCallError, + mox_helper.CallableClass, 8, 9) + self.mox.UnsetStubs() - def testStubOutClassTooManyCreated(self): - self.mox.StubOutClassWithMocks(mox_helper, 'CallableClass') + def testStubOutClassTooManyCreated(self): + self.mox.StubOutClassWithMocks(mox_helper, 'CallableClass') - mox_helper.CallableClass(1, 2) + mox_helper.CallableClass(1, 2) - self.mox.ReplayAll() - mox_helper.CallableClass(1, 2) - self.assertRaises(mox.UnexpectedMockCreationError, - mox_helper.CallableClass, 8, 9) + self.mox.ReplayAll() + mox_helper.CallableClass(1, 2) + self.assertRaises(mox.UnexpectedMockCreationError, + mox_helper.CallableClass, 8, 9) - self.mox.UnsetStubs() + self.mox.UnsetStubs() - def testWarnsUserIfMockingMock(self): - """Test that user is warned if they try to stub out a MockAnything.""" - self.mox.StubOutWithMock(TestClass, 'MyStaticMethod') - self.assertRaises(TypeError, self.mox.StubOutWithMock, TestClass, - 'MyStaticMethod') + def testWarnsUserIfMockingMock(self): + """Test that user is warned if they try to stub out a MockAnything.""" + self.mox.StubOutWithMock(TestClass, 'MyStaticMethod') + self.assertRaises(TypeError, self.mox.StubOutWithMock, TestClass, + 'MyStaticMethod') - def testStubOutFirstClassMethodVerifiesSignature(self): - self.mox.StubOutWithMock(mox_helper, 'MyTestFunction') + def testStubOutFirstClassMethodVerifiesSignature(self): + self.mox.StubOutWithMock(mox_helper, 'MyTestFunction') - # Wrong number of arguments - self.assertRaises(AttributeError, mox_helper.MyTestFunction, 1) - self.mox.UnsetStubs() + # Wrong number of arguments + self.assertRaises(AttributeError, mox_helper.MyTestFunction, 1) + self.mox.UnsetStubs() - def _testMethodSignatureVerification(self, stubClass): - # If stubClass is true, the test is run against an a stubbed out class, - # else the test is run against a stubbed out instance. - if stubClass: - self.mox.StubOutWithMock(mox_helper.ExampleClass, "TestMethod") - obj = mox_helper.ExampleClass() - else: - obj = mox_helper.ExampleClass() - self.mox.StubOutWithMock(mox_helper.ExampleClass, "TestMethod") - self.assertRaises(AttributeError, obj.TestMethod) - self.assertRaises(AttributeError, obj.TestMethod, 1) - self.assertRaises(AttributeError, obj.TestMethod, nine=2) - obj.TestMethod(1, 2) - obj.TestMethod(1, 2, 3) - obj.TestMethod(1, 2, nine=3) - self.assertRaises(AttributeError, obj.TestMethod, 1, 2, 3, 4) - self.mox.UnsetStubs() + def _testMethodSignatureVerification(self, stubClass): + # If stubClass is true, the test is run against an a stubbed out class, + # else the test is run against a stubbed out instance. + if stubClass: + self.mox.StubOutWithMock(mox_helper.ExampleClass, "TestMethod") + obj = mox_helper.ExampleClass() + else: + obj = mox_helper.ExampleClass() + self.mox.StubOutWithMock(mox_helper.ExampleClass, "TestMethod") + self.assertRaises(AttributeError, obj.TestMethod) + self.assertRaises(AttributeError, obj.TestMethod, 1) + self.assertRaises(AttributeError, obj.TestMethod, nine=2) + obj.TestMethod(1, 2) + obj.TestMethod(1, 2, 3) + obj.TestMethod(1, 2, nine=3) + self.assertRaises(AttributeError, obj.TestMethod, 1, 2, 3, 4) + self.mox.UnsetStubs() - def testStubOutClassMethodVerifiesSignature(self): - self._testMethodSignatureVerification(stubClass=True) + def testStubOutClassMethodVerifiesSignature(self): + self._testMethodSignatureVerification(stubClass=True) - def testStubOutObjectMethodVerifiesSignature(self): - self._testMethodSignatureVerification(stubClass=False) + def testStubOutObjectMethodVerifiesSignature(self): + self._testMethodSignatureVerification(stubClass=False) - def testStubOutObject(self): - """Test than object is replaced with a Mock.""" + def testStubOutObject(self): + """Test than object is replaced with a Mock.""" - class Foo(object): - def __init__(self): - self.obj = TestClass() - - foo = Foo() - self.mox.StubOutWithMock(foo, "obj") - self.assertTrue(isinstance(foo.obj, mox.MockObject)) - foo.obj.ValidCall() - self.mox.ReplayAll() - - foo.obj.ValidCall() - - self.mox.VerifyAll() - self.mox.UnsetStubs() - self.assertFalse(isinstance(foo.obj, mox.MockObject)) - - def testForgotReplayHelpfulMessage(self): - """If there is an AttributeError on a MockMethod, give users a helpful msg. - """ - foo = self.mox.CreateMockAnything() - bar = self.mox.CreateMockAnything() - foo.GetBar().AndReturn(bar) - bar.ShowMeTheMoney() - # Forgot to replay! - try: - foo.GetBar().ShowMeTheMoney() - except AttributeError as e: - self.assertEqual('MockMethod has no attribute "ShowMeTheMoney". ' - 'Did you remember to put your mocks in replay mode?', str(e)) + class Foo(object): + def __init__(self): + self.obj = TestClass() + + foo = Foo() + self.mox.StubOutWithMock(foo, "obj") + self.assertTrue(isinstance(foo.obj, mox.MockObject)) + foo.obj.ValidCall() + self.mox.ReplayAll() + + foo.obj.ValidCall() + + self.mox.VerifyAll() + self.mox.UnsetStubs() + self.assertFalse(isinstance(foo.obj, mox.MockObject)) + + def testForgotReplayHelpfulMessage(self): + """If there is an AttributeError on a MockMethod, give users a helpful msg. + """ + foo = self.mox.CreateMockAnything() + bar = self.mox.CreateMockAnything() + foo.GetBar().AndReturn(bar) + bar.ShowMeTheMoney() + # Forgot to replay! + try: + foo.GetBar().ShowMeTheMoney() + except AttributeError as e: + self.assertEqual('MockMethod has no attribute "ShowMeTheMoney". ' + 'Did you remember to put your mocks in replay mode?', str(e)) class ReplayTest(unittest.TestCase): - """Verify Replay works properly.""" + """Verify Replay works properly.""" - def testReplay(self): - """Replay should put objects into replay mode.""" - mock_obj = mox.MockObject(TestClass) - self.assertFalse(mock_obj._replay_mode) - mox.Replay(mock_obj) - self.assertTrue(mock_obj._replay_mode) + def testReplay(self): + """Replay should put objects into replay mode.""" + mock_obj = mox.MockObject(TestClass) + self.assertFalse(mock_obj._replay_mode) + mox.Replay(mock_obj) + self.assertTrue(mock_obj._replay_mode) class MoxTestBaseTest(unittest.TestCase): - """Verify that all tests in a class derived from MoxTestBase are wrapped.""" + """Verify that all tests in a class derived from MoxTestBase are wrapped.""" - def setUp(self): - self.mox = mox.Mox() - self.test_mox = mox.Mox() - self.test_stubs = mox.stubout.StubOutForTesting() - self.result = unittest.TestResult() + def setUp(self): + self.mox = mox.Mox() + self.test_mox = mox.Mox() + self.test_stubs = mox.stubout.StubOutForTesting() + self.result = unittest.TestResult() - def tearDown(self): - self.mox.UnsetStubs() - self.test_mox.UnsetStubs() - self.test_stubs.UnsetAll() - self.test_stubs.SmartUnsetAll() + def tearDown(self): + self.mox.UnsetStubs() + self.test_mox.UnsetStubs() + self.test_stubs.UnsetAll() + self.test_stubs.SmartUnsetAll() - def _setUpTestClass(self): - """Replacement for setUp in the test class instance. + def _setUpTestClass(self): + """Replacement for setUp in the test class instance. - Assigns a mox.Mox instance as the mox attribute of the test class instance. - This replacement Mox instance is under our control before setUp is called - in the test class instance. - """ - self.test.mox = self.test_mox - self.test.stubs = self.test_stubs + Assigns a mox.Mox instance as the mox attribute of the test class instance. + This replacement Mox instance is under our control before setUp is called + in the test class instance. + """ + self.test.mox = self.test_mox + self.test.stubs = self.test_stubs - def _CreateTest(self, test_name): - """Create a test from our example mox class. + def _CreateTest(self, test_name): + """Create a test from our example mox class. - The created test instance is assigned to this instances test attribute. - """ - self.test = mox_helper.ExampleMoxTest(test_name) - self.mox.stubs.Set(self.test, 'setUp', self._setUpTestClass) + The created test instance is assigned to this instances test attribute. + """ + self.test = mox_helper.ExampleMoxTest(test_name) + self.mox.stubs.Set(self.test, 'setUp', self._setUpTestClass) - def _VerifySuccess(self): - """Run the checks to confirm test method completed successfully.""" - self.mox.StubOutWithMock(self.test_mox, 'UnsetStubs') - self.mox.StubOutWithMock(self.test_mox, 'VerifyAll') - self.mox.StubOutWithMock(self.test_stubs, 'UnsetAll') - self.mox.StubOutWithMock(self.test_stubs, 'SmartUnsetAll') - self.test_mox.UnsetStubs() - self.test_mox.VerifyAll() - self.test_stubs.UnsetAll() - self.test_stubs.SmartUnsetAll() - self.mox.ReplayAll() - self.test.run(result=self.result) - self.assertTrue(self.result.wasSuccessful()) - self.mox.VerifyAll() - self.mox.UnsetStubs() # Needed to call the real VerifyAll() below. - self.test_mox.VerifyAll() + def _VerifySuccess(self): + """Run the checks to confirm test method completed successfully.""" + self.mox.StubOutWithMock(self.test_mox, 'UnsetStubs') + self.mox.StubOutWithMock(self.test_mox, 'VerifyAll') + self.mox.StubOutWithMock(self.test_stubs, 'UnsetAll') + self.mox.StubOutWithMock(self.test_stubs, 'SmartUnsetAll') + self.test_mox.UnsetStubs() + self.test_mox.VerifyAll() + self.test_stubs.UnsetAll() + self.test_stubs.SmartUnsetAll() + self.mox.ReplayAll() + self.test.run(result=self.result) + self.assertTrue(self.result.wasSuccessful()) + self.mox.VerifyAll() + self.mox.UnsetStubs() # Needed to call the real VerifyAll() below. + self.test_mox.VerifyAll() - def testSuccess(self): - """Successful test method execution test.""" - self._CreateTest('testSuccess') - self._VerifySuccess() + def testSuccess(self): + """Successful test method execution test.""" + self._CreateTest('testSuccess') + self._VerifySuccess() - def testSuccessNoMocks(self): - """Let testSuccess() unset all the mocks, and verify they've been unset.""" - self._CreateTest('testSuccess') - self.test.run(result=self.result) - self.assertTrue(self.result.wasSuccessful()) - self.assertEqual(OS_LISTDIR, mox_helper.os.listdir) + def testSuccessNoMocks(self): + """Let testSuccess() unset all the mocks, and verify they've been unset.""" + self._CreateTest('testSuccess') + self.test.run(result=self.result) + self.assertTrue(self.result.wasSuccessful()) + self.assertEqual(OS_LISTDIR, mox_helper.os.listdir) - def testStubs(self): - """Test that "self.stubs" is provided as is useful.""" - self._CreateTest('testHasStubs') - self._VerifySuccess() + def testStubs(self): + """Test that "self.stubs" is provided as is useful.""" + self._CreateTest('testHasStubs') + self._VerifySuccess() - def testStubsNoMocks(self): - """Let testHasStubs() unset the stubs by itself.""" - self._CreateTest('testHasStubs') - self.test.run(result=self.result) - self.assertTrue(self.result.wasSuccessful()) - self.assertEqual(OS_LISTDIR, mox_helper.os.listdir) + def testStubsNoMocks(self): + """Let testHasStubs() unset the stubs by itself.""" + self._CreateTest('testHasStubs') + self.test.run(result=self.result) + self.assertTrue(self.result.wasSuccessful()) + self.assertEqual(OS_LISTDIR, mox_helper.os.listdir) - def testExpectedNotCalled(self): - """Stubbed out method is not called.""" - self._CreateTest('testExpectedNotCalled') - self.mox.StubOutWithMock(self.test_mox, 'UnsetStubs') - self.mox.StubOutWithMock(self.test_stubs, 'UnsetAll') - self.mox.StubOutWithMock(self.test_stubs, 'SmartUnsetAll') - # Don't stub out VerifyAll - that's what causes the test to fail - self.test_mox.UnsetStubs() - self.test_stubs.UnsetAll() - self.test_stubs.SmartUnsetAll() - self.mox.ReplayAll() - self.test.run(result=self.result) - self.assertFalse(self.result.wasSuccessful()) - self.mox.VerifyAll() + def testExpectedNotCalled(self): + """Stubbed out method is not called.""" + self._CreateTest('testExpectedNotCalled') + self.mox.StubOutWithMock(self.test_mox, 'UnsetStubs') + self.mox.StubOutWithMock(self.test_stubs, 'UnsetAll') + self.mox.StubOutWithMock(self.test_stubs, 'SmartUnsetAll') + # Don't stub out VerifyAll - that's what causes the test to fail + self.test_mox.UnsetStubs() + self.test_stubs.UnsetAll() + self.test_stubs.SmartUnsetAll() + self.mox.ReplayAll() + self.test.run(result=self.result) + self.assertFalse(self.result.wasSuccessful()) + self.mox.VerifyAll() - def testExpectedNotCalledNoMocks(self): - """Let testExpectedNotCalled() unset all the mocks by itself.""" - self._CreateTest('testExpectedNotCalled') - self.test.run(result=self.result) - self.assertFalse(self.result.wasSuccessful()) - self.assertEqual(OS_LISTDIR, mox_helper.os.listdir) + def testExpectedNotCalledNoMocks(self): + """Let testExpectedNotCalled() unset all the mocks by itself.""" + self._CreateTest('testExpectedNotCalled') + self.test.run(result=self.result) + self.assertFalse(self.result.wasSuccessful()) + self.assertEqual(OS_LISTDIR, mox_helper.os.listdir) - def testUnexpectedCall(self): - """Stubbed out method is called with unexpected arguments.""" - self._CreateTest('testUnexpectedCall') - self.mox.StubOutWithMock(self.test_mox, 'UnsetStubs') - self.mox.StubOutWithMock(self.test_stubs, 'UnsetAll') - self.mox.StubOutWithMock(self.test_stubs, 'SmartUnsetAll') - # Ensure no calls are made to VerifyAll() - self.mox.StubOutWithMock(self.test_mox, 'VerifyAll') - self.test_mox.UnsetStubs() - self.test_stubs.UnsetAll() - self.test_stubs.SmartUnsetAll() - self.mox.ReplayAll() - self.test.run(result=self.result) - self.assertFalse(self.result.wasSuccessful()) - self.mox.VerifyAll() + def testUnexpectedCall(self): + """Stubbed out method is called with unexpected arguments.""" + self._CreateTest('testUnexpectedCall') + self.mox.StubOutWithMock(self.test_mox, 'UnsetStubs') + self.mox.StubOutWithMock(self.test_stubs, 'UnsetAll') + self.mox.StubOutWithMock(self.test_stubs, 'SmartUnsetAll') + # Ensure no calls are made to VerifyAll() + self.mox.StubOutWithMock(self.test_mox, 'VerifyAll') + self.test_mox.UnsetStubs() + self.test_stubs.UnsetAll() + self.test_stubs.SmartUnsetAll() + self.mox.ReplayAll() + self.test.run(result=self.result) + self.assertFalse(self.result.wasSuccessful()) + self.mox.VerifyAll() - def testFailure(self): - """Failing assertion in test method.""" - self._CreateTest('testFailure') - self.mox.StubOutWithMock(self.test_mox, 'UnsetStubs') - self.mox.StubOutWithMock(self.test_stubs, 'UnsetAll') - self.mox.StubOutWithMock(self.test_stubs, 'SmartUnsetAll') - # Ensure no calls are made to VerifyAll() - self.mox.StubOutWithMock(self.test_mox, 'VerifyAll') - self.test_mox.UnsetStubs() - self.test_stubs.UnsetAll() - self.test_stubs.SmartUnsetAll() - self.mox.ReplayAll() - self.test.run(result=self.result) - self.assertFalse(self.result.wasSuccessful()) - self.mox.VerifyAll() + def testFailure(self): + """Failing assertion in test method.""" + self._CreateTest('testFailure') + self.mox.StubOutWithMock(self.test_mox, 'UnsetStubs') + self.mox.StubOutWithMock(self.test_stubs, 'UnsetAll') + self.mox.StubOutWithMock(self.test_stubs, 'SmartUnsetAll') + # Ensure no calls are made to VerifyAll() + self.mox.StubOutWithMock(self.test_mox, 'VerifyAll') + self.test_mox.UnsetStubs() + self.test_stubs.UnsetAll() + self.test_stubs.SmartUnsetAll() + self.mox.ReplayAll() + self.test.run(result=self.result) + self.assertFalse(self.result.wasSuccessful()) + self.mox.VerifyAll() - def testMixin(self): - """Run test from mix-in test class, ensure it passes.""" - self._CreateTest('testStat') - self._VerifySuccess() + def testMixin(self): + """Run test from mix-in test class, ensure it passes.""" + self._CreateTest('testStat') + self._VerifySuccess() - def testMixinAgain(self): - """Run same test as above but from the current test class. + def testMixinAgain(self): + """Run same test as above but from the current test class. - This ensures metaclass properly wrapped test methods from all base classes. - If unsetting of stubs doesn't happen, this will fail. - """ - self._CreateTest('testStatOther') - self._VerifySuccess() + This ensures metaclass properly wrapped test methods from all base classes. + If unsetting of stubs doesn't happen, this will fail. + """ + self._CreateTest('testStatOther') + self._VerifySuccess() class VerifyTest(unittest.TestCase): - """Verify Verify works properly.""" + """Verify Verify works properly.""" - def testVerify(self): - """Verify should be called for all objects. + def testVerify(self): + """Verify should be called for all objects. - This should throw an exception because the expected behavior did not occur. - """ - mock_obj = mox.MockObject(TestClass) - mock_obj.ValidCall() - mock_obj._Replay() - self.assertRaises(mox.ExpectedMethodCallsError, mox.Verify, mock_obj) + This should throw an exception because the expected behavior did not occur. + """ + mock_obj = mox.MockObject(TestClass) + mock_obj.ValidCall() + mock_obj._Replay() + self.assertRaises(mox.ExpectedMethodCallsError, mox.Verify, mock_obj) class ResetTest(unittest.TestCase): - """Verify Reset works properly.""" + """Verify Reset works properly.""" - def testReset(self): - """Should empty all queues and put mocks in record mode.""" - mock_obj = mox.MockObject(TestClass) - mock_obj.ValidCall() - self.assertFalse(mock_obj._replay_mode) - mock_obj._Replay() - self.assertTrue(mock_obj._replay_mode) - self.assertEqual(1, len(mock_obj._expected_calls_queue)) + def testReset(self): + """Should empty all queues and put mocks in record mode.""" + mock_obj = mox.MockObject(TestClass) + mock_obj.ValidCall() + self.assertFalse(mock_obj._replay_mode) + mock_obj._Replay() + self.assertTrue(mock_obj._replay_mode) + self.assertEqual(1, len(mock_obj._expected_calls_queue)) - mox.Reset(mock_obj) - self.assertFalse(mock_obj._replay_mode) - self.assertEqual(0, len(mock_obj._expected_calls_queue)) + mox.Reset(mock_obj) + self.assertFalse(mock_obj._replay_mode) + self.assertEqual(0, len(mock_obj._expected_calls_queue)) class MyTestCase(unittest.TestCase): - """Simulate the use of a fake wrapper around Python's unittest library.""" + """Simulate the use of a fake wrapper around Python's unittest library.""" - def setUp(self): - super(MyTestCase, self).setUp() - self.critical_variable = 42 - self.another_critical_variable = 42 + def setUp(self): + super(MyTestCase, self).setUp() + self.critical_variable = 42 + self.another_critical_variable = 42 - def testMethodOverride(self): - """Should be properly overriden in a derived class.""" - self.assertEqual(42, self.another_critical_variable) - self.another_critical_variable += 1 + def testMethodOverride(self): + """Should be properly overriden in a derived class.""" + self.assertEqual(42, self.another_critical_variable) + self.another_critical_variable += 1 class MoxTestBaseMultipleInheritanceTest(mox.MoxTestBase, MyTestCase): - """Test that multiple inheritance can be used with MoxTestBase.""" + """Test that multiple inheritance can be used with MoxTestBase.""" - def setUp(self): - super(MoxTestBaseMultipleInheritanceTest, self).setUp() - self.another_critical_variable = 99 + def setUp(self): + super(MoxTestBaseMultipleInheritanceTest, self).setUp() + self.another_critical_variable = 99 - def testMultipleInheritance(self): - """Should be able to access members created by all parent setUp().""" - self.assertTrue(isinstance(self.mox, mox.Mox)) - self.assertEqual(42, self.critical_variable) + def testMultipleInheritance(self): + """Should be able to access members created by all parent setUp().""" + self.assertTrue(isinstance(self.mox, mox.Mox)) + self.assertEqual(42, self.critical_variable) - def testMethodOverride(self): - """Should run before MyTestCase.testMethodOverride.""" - self.assertEqual(99, self.another_critical_variable) - self.another_critical_variable = 42 - super(MoxTestBaseMultipleInheritanceTest, self).testMethodOverride() - self.assertEqual(43, self.another_critical_variable) + def testMethodOverride(self): + """Should run before MyTestCase.testMethodOverride.""" + self.assertEqual(99, self.another_critical_variable) + self.another_critical_variable = 42 + super(MoxTestBaseMultipleInheritanceTest, self).testMethodOverride() + self.assertEqual(43, self.another_critical_variable) class MoxTestDontMockProperties(MoxTestBaseTest): - def testPropertiesArentMocked(self): - mock_class = self.mox.CreateMock(ClassWithProperties) - self.assertRaises(mox.UnknownMethodCallError, - lambda: mock_class.prop_attr) + def testPropertiesArentMocked(self): + mock_class = self.mox.CreateMock(ClassWithProperties) + self.assertRaises(mox.UnknownMethodCallError, + lambda: mock_class.prop_attr) class TestClass(object): - """This class is used only for testing the mock framework""" + """This class is used only for testing the mock framework""" - SOME_CLASS_VAR = "test_value" - _PROTECTED_CLASS_VAR = "protected value" + SOME_CLASS_VAR = "test_value" + _PROTECTED_CLASS_VAR = "protected value" - def __init__(self, ivar=None): - self.__ivar = ivar + def __init__(self, ivar=None): + self.__ivar = ivar - def __eq__(self, rhs): - return self.__ivar == rhs + def __eq__(self, rhs): + return self.__ivar == rhs - def __ne__(self, rhs): - return not self.__eq__(rhs) + def __ne__(self, rhs): + return not self.__eq__(rhs) - def ValidCall(self): - pass + def ValidCall(self): + pass - def MethodWithArgs(self, one, two, nine=None): - pass + def MethodWithArgs(self, one, two, nine=None): + pass - def OtherValidCall(self): - pass + def OtherValidCall(self): + pass - def OptionalArgs(self, foo='boom'): - pass + def OptionalArgs(self, foo='boom'): + pass - def ValidCallWithArgs(self, *args, **kwargs): - pass + def ValidCallWithArgs(self, *args, **kwargs): + pass - @classmethod - def MyClassMethod(cls): - pass + @classmethod + def MyClassMethod(cls): + pass - @staticmethod - def MyStaticMethod(): - pass + @staticmethod + def MyStaticMethod(): + pass - def _ProtectedCall(self): - pass + def _ProtectedCall(self): + pass - def __PrivateCall(self): - pass + def __PrivateCall(self): + pass - def __DoNotMock(self): - pass + def __DoNotMock(self): + pass - def __getitem__(self, key): - """Return the value for key.""" - return self.d[key] + def __getitem__(self, key): + """Return the value for key.""" + return self.d[key] - def __setitem__(self, key, value): - """Set the value for key to value.""" - self.d[key] = value + def __setitem__(self, key, value): + """Set the value for key to value.""" + self.d[key] = value - def __contains__(self, key): - """Returns True if d contains the key.""" - return key in self.d + def __contains__(self, key): + """Returns True if d contains the key.""" + return key in self.d - def __iter__(self): - pass + def __iter__(self): + pass class ChildClass(TestClass): - """This inherits from TestClass.""" - def __init__(self): - TestClass.__init__(self) + """This inherits from TestClass.""" + def __init__(self): + TestClass.__init__(self) - def ChildValidCall(self): - pass + def ChildValidCall(self): + pass class CallableClass(object): - """This class is callable, and that should be mockable!""" + """This class is callable, and that should be mockable!""" - def __init__(self): - pass + def __init__(self): + pass - def __call__(self, param): - return param + def __call__(self, param): + return param class ClassWithProperties(object): - def setter_attr(self, value): - pass + def setter_attr(self, value): + pass - def getter_attr(self): - pass + def getter_attr(self): + pass - prop_attr = property(getter_attr, setter_attr) + prop_attr = property(getter_attr, setter_attr) class SubscribtableNonIterableClass(object): - def __getitem__(self, index): - raise IndexError + def __getitem__(self, index): + raise IndexError class InheritsFromCallable(CallableClass): - """This class should also be mockable; it inherits from a callable class.""" + """This class should also be mockable; it inherits from a callable class.""" - pass + pass if __name__ == '__main__': - unittest.main() + unittest.main() diff --git a/mox3/tests/test_stubout.py b/mox3/tests/test_stubout.py index be9a94c..e729d34 100644 --- a/mox3/tests/test_stubout.py +++ b/mox3/tests/test_stubout.py @@ -23,26 +23,26 @@ from . import stubout_helper class StubOutForTestingTest(unittest.TestCase): - def setUp(self): - self.mox = mox.Mox() - self.sample_function_backup = stubout_helper.SampleFunction + def setUp(self): + self.mox = mox.Mox() + self.sample_function_backup = stubout_helper.SampleFunction - def tearDown(self): - stubout_helper.SampleFunction = self.sample_function_backup + def tearDown(self): + stubout_helper.SampleFunction = self.sample_function_backup - def testSmartSetOnModule(self): - mock_function = self.mox.CreateMockAnything() - mock_function() + def testSmartSetOnModule(self): + mock_function = self.mox.CreateMockAnything() + mock_function() - stubber = stubout.StubOutForTesting() - stubber.SmartSet(stubout_helper, 'SampleFunction', mock_function) + stubber = stubout.StubOutForTesting() + stubber.SmartSet(stubout_helper, 'SampleFunction', mock_function) - self.mox.ReplayAll() + self.mox.ReplayAll() - stubout_helper.SampleFunction() + stubout_helper.SampleFunction() - self.mox.VerifyAll() + self.mox.VerifyAll() if __name__ == '__main__': - unittest.main() + unittest.main() diff --git a/setup.py b/setup.py index b3e85a7..0c9e136 100644 --- a/setup.py +++ b/setup.py @@ -17,5 +17,5 @@ import setuptools setuptools.setup( - setup_requires=['d2to1>=0.2.10,<0.3', 'pbr>=0.5.10,<0.6'], - d2to1=True) + setup_requires=['d2to1>=0.2.10,<0.3', 'pbr>=0.5.10,<0.6'], + d2to1=True) diff --git a/tox.ini b/tox.ini index 2b30581..69c834e 100644 --- a/tox.ini +++ b/tox.ini @@ -22,6 +22,6 @@ commands = [flake8] show-source = true -ignore = H,E11 +ignore = H builtins = _ exclude=.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg