Fix all of the flake8/hacking warnings.

This commit is contained in:
Monty Taylor 2013-05-21 18:37:02 -04:00
parent 1a99638ba2
commit 4b4421e766
7 changed files with 405 additions and 356 deletions

View File

@ -12,7 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# This is a fork of the pymox library intended to work with Python 3.
# The file was modified by quermit@gmail.com and dawid.fatyga@gmail.com
@ -63,14 +62,14 @@ Suggested usage / workflow:
my_mox.VerifyAll()
"""
from collections import deque
import collections
import difflib
import inspect
import re
import types
import unittest
from . import stubout
from mox3 import stubout
class Error(AssertionError):
@ -164,9 +163,7 @@ class UnknownMethodCallError(Error):
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)
@ -261,7 +258,8 @@ class Mox(object):
"""
if attrs is None:
attrs = {}
new_mock = MockObject(class_to_mock, attrs=attrs, class_to_bind=bounded_to)
new_mock = MockObject(class_to_mock, attrs=attrs,
class_to_bind=bounded_to)
self._mock_objects.append(new_mock)
return new_mock
@ -271,8 +269,8 @@ class Mox(object):
This does not enforce an interface.
Args:
description: str. Optionally, a descriptive name for the mock object
being created, for debugging output purposes.
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)
@ -299,15 +297,16 @@ class Mox(object):
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.
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):
@ -320,16 +319,17 @@ class Mox(object):
if attr_type == MockAnything or attr_type == MockObject:
raise TypeError('Cannot mock a MockAnything! Did you remember to '
'call UnsetStubs in your previous test?')
'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))
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)
description='Stub for %s' % attr_to_replace)
stub.__name__ = attr_name
self.stubs.Set(obj, attr_name, stub)
@ -352,7 +352,7 @@ class Mox(object):
mock1 = mox.CreateMock(my_import.FooClass)
mock2 = mox.CreateMock(my_import.FooClass)
foo_factory = mox.StubOutWithMock(my_import, 'FooClass',
use_mock_anything=True)
use_mock_anything=True)
foo_factory(1, 2).AndReturn(mock1)
foo_factory(9, 10).AndReturn(mock2)
mox.ReplayAll()
@ -377,10 +377,10 @@ class Mox(object):
if attr_type == MockAnything or attr_type == MockObject:
raise TypeError('Cannot mock a MockAnything! Did you remember to '
'call UnsetStubs in your previous test?')
'call UnsetStubs in your previous test?')
if not inspect.isclass(attr_to_replace):
raise TypeError('Given attr is not a Class. Use StubOutWithMock.')
raise TypeError('Given attr is not a Class. Use StubOutWithMock.')
factory = _MockObjectFactory(attr_to_replace, self)
self._mock_objects.append(factory)
@ -435,8 +435,8 @@ class MockAnything(object):
"""Initialize a new MockAnything.
Args:
description: str. Optionally, a descriptive name for the mock object
being created, for debugging output purposes.
description: str. Optionally, a descriptive name for the mock
object being created, for debugging output purposes.
"""
self._description = description
self._Reset()
@ -476,13 +476,15 @@ class MockAnything(object):
return self._CreateMockMethod('__getitem__')(i)
def _CreateMockMethod(self, method_name, method_to_mock=None,
class_to_bind=object):
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_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
@ -491,9 +493,9 @@ class MockAnything(object):
"""
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)
self._replay_mode, method_to_mock=method_to_mock,
description=self._description,
class_to_bind=class_to_bind)
def __nonzero__(self):
"""Return 1 for nonzero so the mock can be used as a conditional."""
@ -508,8 +510,8 @@ class MockAnything(object):
"""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)
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."""
@ -525,15 +527,16 @@ class MockAnything(object):
"""Verify that all of the expected calls have been made.
Raises:
ExpectedMethodCallsError: if there are still more method calls in the
expected queue.
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
isinstance(self._expected_calls_queue[0],
MultipleTimesGroup) and
self._expected_calls_queue[0].IsSatisfied()):
pass
else:
@ -543,27 +546,27 @@ class MockAnything(object):
"""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()
self._expected_calls_queue = collections.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."""
"""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.
This determines the methods and properties of the class and stores them.
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
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.
@ -572,7 +575,7 @@ class MockObject(MockAnything):
if attrs is None:
attrs = {}
# This is used to hack around the mixin/inheritance of MockAnything, which
# Used to hack around the mixin/inheritance of MockAnything, which
# is not a proper object (it can be anything. :-)
MockAnything.__dict__['__init__'](self)
@ -610,20 +613,20 @@ class MockObject(MockAnything):
raise PrivateAttributeError(attr)
elif attr in self._known_methods:
raise ValueError("'%s' is a method of '%s' objects." % (attr,
class_to_mock))
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."""
"""Overridden to provide self._class_to_mock to class_to_bind."""
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 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
@ -636,12 +639,12 @@ class MockObject(MockAnything):
name: str
Returns:
Either a class variable or a new MockMethod that is aware of the state
of the mock (record or replay).
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.
UnknownMethodCallError if the MockObject does not mock the
requested method.
"""
if name in self._known_vars:
@ -649,8 +652,8 @@ class MockObject(MockAnything):
if name in self._known_methods:
return self._CreateMockMethod(
name,
method_to_mock=getattr(self._class_to_mock, name))
name,
method_to_mock=getattr(self._class_to_mock, name))
raise UnknownMethodCallError(name)
@ -658,20 +661,21 @@ class MockObject(MockAnything):
"""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)
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.
"""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.
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.
@ -683,10 +687,10 @@ class MockObject(MockAnything):
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 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)
self._replay_mode)(key, value)
# Otherwise, create a mock method __setitem__.
return self._CreateMockMethod('__setitem__')(key, value)
@ -698,8 +702,9 @@ class MockObject(MockAnything):
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.
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.
@ -711,10 +716,10 @@ class MockObject(MockAnything):
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 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)
self._replay_mode)(key)
# Otherwise, create a mock method __getitem__.
return self._CreateMockMethod('__getitem__')(key)
@ -723,7 +728,7 @@ class MockObject(MockAnything):
"""Provide custom logic for mocking classes that are iterable.
Returns:
Expected return value in replay mode. A MockMethod object for the
Expected return value in replay mode. A MockMethod object for the
__iter__ method that has already been called if not in replay mode.
Raises:
@ -736,8 +741,8 @@ class MockObject(MockAnything):
# 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 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:
@ -753,7 +758,7 @@ class MockObject(MockAnything):
# 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)()
self._replay_mode)()
# Otherwise, create a mock method __iter__.
return self._CreateMockMethod('__iter__')()
@ -765,8 +770,9 @@ class MockObject(MockAnything):
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.
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__
@ -781,7 +787,7 @@ class MockObject(MockAnything):
if self._replay_mode:
return MockMethod('__contains__', self._expected_calls_queue,
self._replay_mode)(key)
self._replay_mode)(key)
return self._CreateMockMethod('__contains__')(key)
@ -820,11 +826,11 @@ class MockObject(MockAnything):
return self._class_to_mock
def __dir__(self):
"""Return only attributes of a class to mock """
"""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. """
"""Return _class_to_mock on __class__ attribute."""
if name == "__class__":
return super(MockObject, self).__getattribute__("_class_to_mock")
@ -838,8 +844,8 @@ class _MockObjectFactory(MockObject):
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.
__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.
"""
@ -847,7 +853,7 @@ class _MockObjectFactory(MockObject):
def __init__(self, class_to_mock, mox_instance):
MockObject.__init__(self, class_to_mock)
self._mox = mox_instance
self._instance_queue = deque()
self._instance_queue = collections.deque()
def __call__(self, *params, **named_params):
"""Instantiate and record that a new mock has been created."""
@ -860,7 +866,7 @@ class _MockObjectFactory(MockObject):
if self._replay_mode:
if not self._instance_queue:
raise UnexpectedMockCreationError(self._class_to_mock, *params,
**named_params)
**named_params)
mock_method(*params, **named_params)
@ -889,20 +895,21 @@ class MethodSignatureChecker(object):
Args:
# method: A method to check.
# class_to_bind: optionally, a class used to type check first method
# parameter, only used with unbound methods
# 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.
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,))
% (method,))
if inspect.ismethod(method) or class_to_bind:
self._args = self._args[1:] # Skip 'self'.
self._method = method
@ -913,7 +920,8 @@ class MethodSignatureChecker(object):
if self._instance:
self._bounded_to = self._instance.__class__
else:
self._bounded_to = class_to_bind or getattr(method, "im_class", None)
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
@ -929,7 +937,8 @@ class MethodSignatureChecker(object):
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_status: Maps argument names to one of
# _NEEDED, _DEFAULT, _GIVEN.
arg_name: string
arg_status: dict
@ -950,10 +959,11 @@ class MethodSignatureChecker(object):
named_params: dict
Raises:
AttributeError: the given parameters don't work with the given method.
AttributeError: the given parameters don't work with the given
method.
"""
arg_status = dict((a, MethodSignatureChecker._NEEDED)
for a in self._required_args)
for a in self._required_args)
for arg in self._default_args:
arg_status[arg] = MethodSignatureChecker._DEFAULT
@ -979,16 +989,17 @@ class MethodSignatureChecker(object):
# an exception during this comparison, which is OK.
try:
param_equality = (params[0] == expected)
except:
except Exception:
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):
# 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.
@ -997,8 +1008,9 @@ class MethodSignatureChecker(object):
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))
raise AttributeError(
'%s does not take %d or more positional '
'arguments' % (self._method.__name__, i))
else:
self._RecordArgumentGiven(arg_name, arg_status)
@ -1006,15 +1018,15 @@ class MethodSignatureChecker(object):
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._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 v == MethodSignatureChecker._NEEDED]
if still_needed:
raise AttributeError('No values given for arguments: %s'
% (' '.join(sorted(still_needed))))
% (' '.join(sorted(still_needed))))
class MockMethod(object):
@ -1027,22 +1039,25 @@ class MockMethod(object):
"""
def __init__(self, method_name, call_queue, replay_mode,
method_to_mock=None, description=None, class_to_bind=None):
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
# 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
@ -1054,8 +1069,8 @@ class MockMethod(object):
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)
if not isinstance(call_queue, collections.deque):
self._call_queue = collections.deque(self._call_queue)
self._replay_mode = replay_mode
self._description = description
@ -1067,21 +1082,21 @@ class MockMethod(object):
try:
self._checker = MethodSignatureChecker(method_to_mock,
class_to_bind=class_to_bind)
class_to_bind=class_to_bind)
except ValueError:
self._checker = None
def __call__(self, *params, **named_params):
"""Log parameters and return the specified return value.
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 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.
Raises:
UnexpectedMethodCall if this call is supposed to match an expected method
call and it does not.
UnexpectedMethodCall if this call is supposed to match an expected
method call and it does not.
"""
self._params = params
@ -1108,23 +1123,27 @@ class MockMethod(object):
def __getattr__(self, name):
"""Raise an AttributeError with a helpful message."""
raise AttributeError('MockMethod has no attribute "%s". '
'Did you remember to put your mocks in replay mode?' % name)
raise AttributeError(
'MockMethod has no attribute "%s". '
'Did you remember to put your mocks in replay mode?' % name)
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?')
raise TypeError(
'MockMethod cannot be iterated. '
'Did you remember to put your mocks in replay mode?')
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 TypeError(
'MockMethod cannot be iterated. '
'Did you remember to put your mocks in replay mode?')
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 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."""
@ -1162,8 +1181,8 @@ class MockMethod(object):
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())])
[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)
@ -1181,12 +1200,12 @@ class MockMethod(object):
"""
return (isinstance(rhs, MockMethod) and
self._name == rhs._name and
self._params == rhs._params and
self._named_params == rhs._named_params)
self._name == rhs._name and
self._params == rhs._params and
self._named_params == rhs._named_params)
def __ne__(self, rhs):
"""Test whether this MockMethod is not equivalent to another MockMethod.
"""Test if this MockMethod is not equivalent to another MockMethod.
Args:
# rhs: the right hand side of the test
@ -1196,8 +1215,9 @@ class MockMethod(object):
return not self == rhs
def GetPossibleGroup(self):
"""Returns a possible group from the end of the call queue or None if no
other methods are on the stack.
"""Returns a possible group from the end of the call queue.
Return None if no other methods are on the stack.
"""
# Remove this method from the tail of the queue so we can add it
@ -1205,8 +1225,8 @@ class MockMethod(object):
this_method = self._call_queue.pop()
assert this_method == self
# Determine if the tail of the queue is a group, or just a regular ordered
# mock method.
# 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]
@ -1217,7 +1237,8 @@ class MockMethod(object):
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.
group_class. Adds the current method to this group or creates a
new one.
Args:
@ -1240,12 +1261,12 @@ class MockMethod(object):
def InAnyOrder(self, group_name="default"):
"""Move this method into a group of unordered calls.
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.
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.
Args:
group_name: the name of the unordered group.
@ -1256,10 +1277,10 @@ class MockMethod(object):
return self._CheckAndCreateNewGroup(group_name, UnorderedGroup)
def MultipleTimes(self, group_name="default"):
"""Move this method into group of calls which may be called multiple times.
"""Move method into group of calls which may be called multiple times.
A group of repeating calls must be defined together, and must be executed
in full before the next expected method can be called.
A group of repeating calls must be defined together, and must be
executed in full before the next expected method can be called.
Args:
group_name: the name of the unordered group.
@ -1293,8 +1314,8 @@ class MockMethod(object):
"""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.
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.
@ -1307,10 +1328,10 @@ class Comparator:
"""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:
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)
@ -1442,7 +1463,7 @@ class IsAlmost(Comparator):
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.
# Probably because either float_value or rhs is not a number.
return False
def __repr__(self):
@ -1565,7 +1586,8 @@ class Not(Comparator):
"""Checks whether a predicates is False.
Example:
mock_dao.UpdateUsers(Not(ContainsKeyValue('stevepm', stevepm_user_info)))
mock_dao.UpdateUsers(Not(ContainsKeyValue('stevepm',
stevepm_user_info)))
"""
def __init__(self, predicate):
@ -1576,7 +1598,7 @@ class Not(Comparator):
"""
assert isinstance(predicate, Comparator), ("predicate %r must be a"
" Comparator." % predicate)
" Comparator." % predicate)
self._predicate = predicate
def equals(self, rhs):
@ -1630,11 +1652,11 @@ class ContainsKeyValue(Comparator):
def __repr__(self):
return '<map containing the entry \'%s: %s\'>' % (str(self._key),
str(self._value))
str(self._value))
class ContainsAttributeValue(Comparator):
"""Checks whether a passed parameter contains attributes with a given value.
"""Checks whether passed parameter contains attributes with a given value.
Example:
mock_dao.UpdateSomething(ContainsAttribute('stevepm', stevepm_user_info))
@ -1690,20 +1712,21 @@ class SameElementsAs(Comparator):
bool
"""
try:
# Store in case actual_seq is an iterator. We potentially iterate twice:
# once to make the dict, once in the list fallback.
# 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.
# 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.
# 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:
@ -1749,8 +1772,7 @@ class And(Comparator):
class Or(Comparator):
"""Evaluates one or more Comparators on RHS and returns an OR of the results.
"""
"""Evaluates one or more Comparators on RHS; returns OR of the results."""
def __init__(self, *args):
"""Initialize.
@ -1784,9 +1806,9 @@ class Or(Comparator):
class Func(Comparator):
"""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:
@ -1831,7 +1853,8 @@ class IgnoreArg(Comparator):
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.
# Check if CastMagic is called with 3 as first arg and
# 'disappear' as third.
mymock.CastMagic(3, IgnoreArg(), 'disappear')
"""
@ -1895,7 +1918,8 @@ class Remember(Comparator):
def __init__(self, value_store):
if not isinstance(value_store, Value):
raise TypeError("value_store is not an instance of the Value class")
raise TypeError(
"value_store is not an instance of the Value class")
self._value_store = value_store
def equals(self, rhs):
@ -1941,9 +1965,9 @@ class UnorderedGroup(MethodGroup):
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))
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.
@ -1961,7 +1985,8 @@ class UnorderedGroup(MethodGroup):
raised.
Args:
mock_method: a mock method that should be equal to a method in the group.
mock_method: a mock method that should be equal to a method in the
group.
Returns:
The mock method from the group
@ -1974,13 +1999,14 @@ class UnorderedGroup(MethodGroup):
# 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.
# 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 this group is not empty, put it back at the head of the queue.
# If group is not empty, put it back at the head of the queue.
if not self.IsSatisfied():
mock_method._call_queue.appendleft(self)
@ -1999,7 +2025,8 @@ class MultipleTimesGroup(MethodGroup):
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.
This is helpful, if you don't know or care how many times a method is
called.
"""
def __init__(self, group_name):
@ -2024,7 +2051,8 @@ class MultipleTimesGroup(MethodGroup):
raised.
Args:
mock_method: a mock method that should be equal to a method in the group.
mock_method: a mock method that should be equal to a method in the
group.
Returns:
The mock method from the group
@ -2038,8 +2066,8 @@ class MultipleTimesGroup(MethodGroup):
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.
# 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
@ -2050,7 +2078,7 @@ class MultipleTimesGroup(MethodGroup):
raise UnexpectedMethodCallError(mock_method, self)
def IsSatisfied(self):
"""Return True if all methods in this group are called at least once."""
"""Return True if all methods in group are called at least once."""
return len(self._methods_left) == 0
@ -2060,8 +2088,8 @@ class MoxMetaTestBase(type):
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.
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):
@ -2087,8 +2115,10 @@ class MoxMetaTestBase(type):
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.
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.
@ -2100,7 +2130,8 @@ class MoxMetaTestBase(type):
cleanup_stubout = False
if mox_obj and isinstance(mox_obj, Mox):
cleanup_mox = True
if stubout_obj and isinstance(stubout_obj, stubout.StubOutForTesting):
if stubout_obj and isinstance(stubout_obj,
stubout.StubOutForTesting):
cleanup_stubout = True
try:
func(self, *args, **kwargs)
@ -2125,10 +2156,10 @@ class MoxTestBase(_MoxTestBase):
"""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.
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):

View File

@ -12,7 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# This is a fork of the pymox library intended to work with Python 3.
# The file was modified by quermit@gmail.com and dawid.fatyga@gmail.com
@ -21,16 +20,17 @@ import inspect
class StubOutForTesting(object):
"""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()
You want os.path.exists() to always return true during testing.
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.
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):
@ -42,24 +42,25 @@ class StubOutForTesting(object):
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.
"""Replace obj.attr_name with new_attr.
This method supports the case where attr_name is a staticmethod or a
classmethod of obj.
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.
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()).
This method supports the case where attr_name is a staticmethod or a
classmethod of obj.
Raises AttributeError if the attribute cannot be found.
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__)):
@ -86,20 +87,22 @@ class StubOutForTesting(object):
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.
# 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):
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.
"""Reverses all the SmartSet() calls.
Restores 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()
@ -109,11 +112,13 @@ class StubOutForTesting(object):
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.
"""Replace child_name's old definition with new_child.
Replace definiion 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.
@ -131,13 +136,15 @@ class StubOutForTesting(object):
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.
"""Reverses all the Set() calls.
Restores 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)
# same arguments repeatedly (want the original call to be last one
# undone)
self.cache.reverse()
for (parent, old_child, child_name) in self.cache:

View File

@ -12,7 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# This is a fork of the pymox library intended to work with Python 3.
# The file was modified by quermit@gmail.com and dawid.fatyga@gmail.com

View File

@ -18,12 +18,12 @@
# The file was modified by quermit@gmail.com and dawid.fatyga@gmail.com
import io
import unittest
import re
import sys
import unittest
from mox3 import mox
from . import mox_helper
from mox3.tests import mox_helper
OS_LISTDIR = mox_helper.os.listdir
@ -40,9 +40,9 @@ class ExpectedMethodCallsErrorTest(unittest.TestCase):
method(1, 2).AndReturn('output')
e = mox.ExpectedMethodCallsError([method])
self.assertEqual(
"Verify: Expected methods never called:\n"
" 0. testMethod(1, 2) -> 'output'",
str(e))
"Verify: Expected methods never called:\n"
" 0. testMethod(1, 2) -> 'output'",
str(e))
def testManyErrors(self):
method1 = mox.MockMethod("testMethod", [], False)
@ -55,12 +55,12 @@ class ExpectedMethodCallsErrorTest(unittest.TestCase):
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))
"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):
@ -96,13 +96,13 @@ class AndTest(unittest.TestCase):
"""
test_dict = {"mock": "obj", "testing": "isCOOL"}
self.assertTrue(mox.And(mox.In("testing"),
mox.ContainsKeyValue("mock", "obj")) == test_dict)
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)
mox.ContainsKeyValue("mock", "obj")) == test_dict)
class FuncTest(unittest.TestCase):
@ -118,7 +118,7 @@ class FuncTest(unittest.TestCase):
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) is None)
def testFuncExceptionPropagation(self):
"""Exceptions within the validating function should propagate."""
@ -133,24 +133,24 @@ class FuncTest(unittest.TestCase):
self.assertTrue(mox.Func(raiseExceptionOnNotOne) == 1)
self.assertRaises(
TestException, mox.Func(raiseExceptionOnNotOne).__eq__, 2)
TestException, mox.Func(raiseExceptionOnNotOne).__eq__, 2)
class SameElementsAsTest(unittest.TestCase):
"""Test SameElementsAs correctly identifies sequences with same elements."""
"""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 testUnsortedLists(self):
"""Should return True if two lists are unequal but have same elements."""
"""Should return True if 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."""
"""Should return True if lists have the same unhashable elements."""
self.assertTrue(mox.SameElementsAs([{'a': 1}, {2: 'b'}]) ==
[{2: 'b'}, {'a': 1}])
[{2: 'b'}, {'a': 1}])
def testEmptyLists(self):
"""Should return True for two empty lists."""
@ -161,8 +161,9 @@ class SameElementsAsTest(unittest.TestCase):
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'}])
"""Should return False if 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."""
@ -196,8 +197,7 @@ class ContainsKeyValueTest(unittest.TestCase):
class ContainsAttributeValueTest(unittest.TestCase):
"""Test ContainsAttributeValue correctly identifies properties in an object.
"""
"""Test ContainsAttributeValue identifies properties in an object."""
def setUp(self):
"""Create an object to test with."""
@ -208,8 +208,9 @@ class ContainsAttributeValueTest(unittest.TestCase):
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)
"""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."""
@ -221,7 +222,7 @@ class ContainsAttributeValueTest(unittest.TestCase):
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."""
@ -262,15 +263,14 @@ class NotTest(unittest.TestCase):
class StrContainsTest(unittest.TestCase):
"""Test StrContains correctly checks for substring occurrence of a parameter.
"""
"""Test StrContains checks for substring occurrence of a parameter."""
def testValidSubstringAtStart(self):
"""Should return True if the substring is at the start of the string."""
"""Should return True if 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."""
"""Should return True if substring is in the middle of the string."""
self.assertTrue(mox.StrContains("lo wo") == "hello world")
def testValidSubstringAtEnd(self):
@ -294,7 +294,7 @@ class RegexTest(unittest.TestCase):
self.assertRaises(re.error, mox.Regex, '(a|b')
def testPatternInMiddle(self):
"""Should return True if the pattern matches at the middle of the string.
"""Return True if the pattern matches at the middle of the string.
This ensures that re.search is used (instead of re.find).
"""
@ -311,16 +311,16 @@ class RegexTest(unittest.TestCase):
def testReprWithoutFlags(self):
"""repr should return the regular expression pattern."""
self.assertTrue(
repr(mox.Regex(r"a\s+b")) == "<regular expression 'a\s+b'>")
repr(mox.Regex(r"a\s+b")) == "<regular expression '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)) ==
"<regular expression 'a\s+b', flags=4>")
"<regular expression '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):
@ -368,7 +368,7 @@ class IsTest(unittest.TestCase):
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."""
@ -439,7 +439,7 @@ class ValueRememberTest(unittest.TestCase):
self.assertEqual(value, 'hello world')
def testNoValue(self):
"""Verify that uninitialized value does not compare to "empty" values."""
"""Verify that uninitialized value does not compare to empty values."""
value = mox.Value()
self.assertNotEqual(value, None)
self.assertNotEqual(value, False)
@ -455,9 +455,9 @@ class ValueRememberTest(unittest.TestCase):
"""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.
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):
@ -465,9 +465,9 @@ class MockMethodTest(unittest.TestCase):
def setUp(self):
self.expected_method = mox.MockMethod(
"testMethod", [], False)(['original'])
self.mock_method = mox.MockMethod("testMethod", [self.expected_method],
True)
"testMethod", [], False)(['original'])
self.mock_method = mox.MockMethod(
"testMethod", [self.expected_method], True)
def testNameAttribute(self):
"""Should provide a __name__ attribute."""
@ -476,7 +476,7 @@ class MockMethodTest(unittest.TestCase):
def testAndReturnNoneByDefault(self):
"""Should return None by default."""
return_value = self.mock_method(['original'])
self.assertTrue(return_value == None)
self.assertTrue(return_value is None)
def testAndReturnValue(self):
"""Should return a specificed return value."""
@ -487,9 +487,12 @@ class MockMethodTest(unittest.TestCase):
def testAndRaiseException(self):
"""Should raise a specified exception."""
expected_exception = Exception('test exception')
class TestException(Exception):
pass
expected_exception = TestException('test exception')
self.expected_method.AndRaise(expected_exception)
self.assertRaises(Exception, self.mock_method)
self.assertRaises(TestException, self.mock_method)
def testWithSideEffects(self):
"""Should call state modifier."""
@ -530,7 +533,7 @@ class MockMethodTest(unittest.TestCase):
return unexpected_return
self.expected_method.WithSideEffects(modifier_with_return).AndReturn(
expected_return)
expected_return)
actual_return = self.mock_method(local_list)
self.assertEqual('mutation', local_list[0])
self.assertEqual(expected_return, actual_return)
@ -541,7 +544,7 @@ class MockMethodTest(unittest.TestCase):
self.assertEqual(self.mock_method, expected_method)
def testEqualityNoParamsNotEqual(self):
"""Methods with different names and without params should not be equal."""
"""Methods with different names without params should not be equal."""
expected_method = mox.MockMethod("otherMethod", [], False)
self.assertNotEqual(self.mock_method, expected_method)
@ -555,7 +558,7 @@ class MockMethodTest(unittest.TestCase):
self.assertEqual(self.mock_method, expected_method)
def testEqualityParamsNotEqual(self):
"""Methods with the same name and different params should not be equal."""
"""Methods with same name and different params should not be equal."""
expected_method = mox.MockMethod("testMethod", [], False)
expected_method._params = [1, 2, 3]
@ -572,11 +575,12 @@ class MockMethodTest(unittest.TestCase):
self.assertEqual(self.mock_method, expected_method)
def testEqualityNamedParamsNotEqual(self):
"""Methods with the same name and diffnamed params should not be equal."""
"""Methods with 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.mock_method._named_params = {
"input1": "test2", "input2": "params2"}
self.assertNotEqual(self.mock_method, expected_method)
def testEqualityWrongType(self):
@ -598,17 +602,18 @@ class MockMethodTest(unittest.TestCase):
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"))
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")
"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")
"testMethod(a=1, b=2, c='only named') -> None")
method = mox.MockMethod("testMethod", [], False)
method()
@ -616,7 +621,8 @@ class MockMethodTest(unittest.TestCase):
method = mox.MockMethod("testMethod", [], False)
method(x="only 1 parameter")
self.assertEqual(str(method), "testMethod(x='only 1 parameter') -> None")
self.assertEqual(str(method),
"testMethod(x='only 1 parameter') -> None")
method = mox.MockMethod("testMethod", [], False)
method().AndReturn('return_value')
@ -660,7 +666,7 @@ class MockAnythingTest(unittest.TestCase):
self.mock_object.ValidCall() # setup method call
self.mock_object._Replay() # start replay mode
self.assertRaises(mox.UnexpectedMethodCallError,
self.mock_object.OtherValidCall)
self.mock_object.OtherValidCall)
def testVerifyWithCompleteReplay(self):
"""Verify should not raise an exception for a valid replay."""
@ -674,10 +680,11 @@ class MockAnythingTest(unittest.TestCase):
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)
self.assertRaises(
mox.ExpectedMethodCallsError, self.mock_object._Verify)
def testSpecialClassMethod(self):
"""Verify should not raise an exception when special methods are used."""
"""Verify should not raise exception when special methods are used."""
self.mock_object[1].AndReturn(True)
self.mock_object._Replay()
returned_val = self.mock_object[1]
@ -769,7 +776,7 @@ class MethodCheckerTest(unittest.TestCase):
instance = CheckCallTestClass()
method = mox.MockMethod('NoParameters', [], False,
CheckCallTestClass.NoParameters)
CheckCallTestClass.NoParameters)
self.assertRaises(AttributeError, method)
method(instance)
@ -777,8 +784,8 @@ class MethodCheckerTest(unittest.TestCase):
def testNoParameters(self):
method = mox.MockMethod('NoParameters', [], False,
CheckCallTestClass.NoParameters,
class_to_bind=CheckCallTestClass)
CheckCallTestClass.NoParameters,
class_to_bind=CheckCallTestClass)
method()
self.assertRaises(AttributeError, method, 1)
self.assertRaises(AttributeError, method, 1, 2)
@ -787,8 +794,8 @@ class MethodCheckerTest(unittest.TestCase):
def testOneParameter(self):
method = mox.MockMethod('OneParameter', [], False,
CheckCallTestClass.OneParameter,
class_to_bind=CheckCallTestClass)
CheckCallTestClass.OneParameter,
class_to_bind=CheckCallTestClass)
self.assertRaises(AttributeError, method)
method(1)
method(a=1)
@ -799,8 +806,8 @@ class MethodCheckerTest(unittest.TestCase):
def testTwoParameters(self):
method = mox.MockMethod('TwoParameters', [], False,
CheckCallTestClass.TwoParameters,
class_to_bind=CheckCallTestClass)
CheckCallTestClass.TwoParameters,
class_to_bind=CheckCallTestClass)
self.assertRaises(AttributeError, method)
self.assertRaises(AttributeError, method, 1)
self.assertRaises(AttributeError, method, a=1)
@ -817,8 +824,8 @@ class MethodCheckerTest(unittest.TestCase):
def testOneDefaultValue(self):
method = mox.MockMethod('OneDefaultValue', [], False,
CheckCallTestClass.OneDefaultValue,
class_to_bind=CheckCallTestClass)
CheckCallTestClass.OneDefaultValue,
class_to_bind=CheckCallTestClass)
method()
method(1)
method(a=1)
@ -829,8 +836,8 @@ class MethodCheckerTest(unittest.TestCase):
def testTwoDefaultValues(self):
method = mox.MockMethod('TwoDefaultValues', [], False,
CheckCallTestClass.TwoDefaultValues,
class_to_bind=CheckCallTestClass)
CheckCallTestClass.TwoDefaultValues,
class_to_bind=CheckCallTestClass)
self.assertRaises(AttributeError, method)
self.assertRaises(AttributeError, method, c=3)
self.assertRaises(AttributeError, method, 1)
@ -850,7 +857,7 @@ class MethodCheckerTest(unittest.TestCase):
def testArgs(self):
method = mox.MockMethod('Args', [], False, CheckCallTestClass.Args,
class_to_bind=CheckCallTestClass)
class_to_bind=CheckCallTestClass)
self.assertRaises(AttributeError, method)
self.assertRaises(AttributeError, method, 1)
method(1, 2)
@ -862,7 +869,7 @@ class MethodCheckerTest(unittest.TestCase):
def testKwargs(self):
method = mox.MockMethod('Kwargs', [], False, CheckCallTestClass.Kwargs,
class_to_bind=CheckCallTestClass)
class_to_bind=CheckCallTestClass)
self.assertRaises(AttributeError, method)
method(1)
method(1, 2)
@ -878,8 +885,8 @@ class MethodCheckerTest(unittest.TestCase):
def testArgsAndKwargs(self):
method = mox.MockMethod('ArgsAndKwargs', [], False,
CheckCallTestClass.ArgsAndKwargs,
class_to_bind=CheckCallTestClass)
CheckCallTestClass.ArgsAndKwargs,
class_to_bind=CheckCallTestClass)
self.assertRaises(AttributeError, method)
method(1)
method(1, 2)
@ -930,7 +937,7 @@ class MockObjectTest(unittest.TestCase):
self.assertTrue(len(self.mock_object._expected_calls_queue) == 1)
def testSetupModeWithInvalidCall(self):
"""UnknownMethodCallError should be raised for a non-member method call.
"""Rase UnknownMethodCallError for a non-member method call.
"""
# Note: assertRaises does not catch exceptions thrown by MockObject's
# __getattr__
@ -940,13 +947,14 @@ class MockObjectTest(unittest.TestCase):
except mox.UnknownMethodCallError:
pass
except Exception:
self.fail("Wrong exception type thrown, expected UnknownMethodCallError")
self.fail("Wrong exception type thrown,"
" expected UnknownMethodCallError")
def testReplayWithInvalidCall(self):
"""UnknownMethodCallError should be raised for a non-member method call.
"""Rase UnknownMethodCallError for a non-member method call.
"""
self.mock_object.ValidCall() # setup method call
self.mock_object._Replay() # start replay mode
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:
@ -955,7 +963,8 @@ class MockObjectTest(unittest.TestCase):
except mox.UnknownMethodCallError:
pass
except Exception:
self.fail("Wrong exception type thrown, expected UnknownMethodCallError")
self.fail("Wrong exception type thrown,"
" expected UnknownMethodCallError")
def testIsInstance(self):
"""Mock should be able to pass as an instance of the mocked class."""
@ -970,7 +979,7 @@ class MockObjectTest(unittest.TestCase):
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)
'_TestClass__PrivateCall' in self.mock_object._known_methods)
def testFindsSuperclassMethods(self):
"""Mock should be able to mock superclasses methods."""
@ -1282,13 +1291,13 @@ class MockObjectTest(unittest.TestCase):
def testCantOverrideMethodsWithAttributes(self):
self.assertRaises(ValueError, mox.MockObject, TestClass,
attrs={"ValidCall": "value"})
attrs={"ValidCall": "value"})
def testCantMockNonPublicAttributes(self):
self.assertRaises(mox.PrivateAttributeError, mox.MockObject, TestClass,
attrs={"_protected": "value"})
attrs={"_protected": "value"})
self.assertRaises(mox.PrivateAttributeError, mox.MockObject, TestClass,
attrs={"__private": "value"})
attrs={"__private": "value"})
class MoxTest(unittest.TestCase):
@ -1299,7 +1308,7 @@ class MoxTest(unittest.TestCase):
def testCreateObject(self):
"""Mox should create a mock object."""
mock_obj = self.mox.CreateMock(TestClass)
self.mox.CreateMock(TestClass)
def testVerifyObjectWithCompleteReplay(self):
"""Mox should replay and verify all objects it created."""
@ -1361,7 +1370,7 @@ class MoxTest(unittest.TestCase):
self.mox.VerifyAll()
def testInheritedCallableObject(self):
"""Test recording calls to an object inheriting from a callable object."""
"""Recording calls to an object inheriting from a callable object."""
mock_obj = self.mox.CreateMock(InheritsFromCallable)
mock_obj("foo").AndReturn("qux")
self.mox.ReplayAll()
@ -1464,7 +1473,7 @@ class MoxTest(unittest.TestCase):
self.mox.VerifyAll()
def testUnorderedGroupWithComparator(self):
"""Unordered groups should work with comparators"""
"""Unordered groups should work with comparators."""
def VerifyOne(cmd):
if not isinstance(cmd, str):
@ -1476,9 +1485,9 @@ class MoxTest(unittest.TestCase):
mock_obj = self.mox.CreateMockAnything()
mock_obj.Foo(['test'], mox.Func(VerifyOne), bar=1).InAnyOrder().\
AndReturn('yes test')
AndReturn('yes test')
mock_obj.Foo(['test'], mox.Func(VerifyTwo), bar=1).InAnyOrder().\
AndReturn('anything')
AndReturn('anything')
self.mox.ReplayAll()
@ -1641,9 +1650,9 @@ class MoxTest(unittest.TestCase):
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(1)
mock_obj.Method(3)
self.assertRaises(mox.UnexpectedMethodCallError, mock_obj.Method, 1)
@ -1652,7 +1661,8 @@ class MoxTest(unittest.TestCase):
def modifier(mutable_list):
mutable_list[0] = 'mutated'
mock_obj = self.mox.CreateMockAnything()
mock_obj.ConfigureInOutParameter(['original']).WithSideEffects(modifier)
mock_obj.ConfigureInOutParameter(
['original']).WithSideEffects(modifier)
mock_obj.WorkWithParameter(['mutated'])
self.mox.ReplayAll()
@ -1664,18 +1674,21 @@ class MoxTest(unittest.TestCase):
def testWithSideEffectsException(self):
"""Test side effect operations actually modify their target objects."""
class TestException(Exception):
pass
def modifier(mutable_list):
mutable_list[0] = 'mutated'
mock_obj = self.mox.CreateMockAnything()
method = mock_obj.ConfigureInOutParameter(['original'])
method.WithSideEffects(modifier).AndRaise(Exception('exception'))
method.WithSideEffects(modifier).AndRaise(TestException('exception'))
mock_obj.WorkWithParameter(['mutated'])
self.mox.ReplayAll()
local_list = ['original']
self.assertRaises(Exception,
mock_obj.ConfigureInOutParameter,
local_list)
self.assertRaises(TestException,
mock_obj.ConfigureInOutParameter,
local_list)
mock_obj.WorkWithParameter(local_list)
self.mox.VerifyAll()
@ -1714,9 +1727,9 @@ class MoxTest(unittest.TestCase):
def testStubOutMethod_Unbound_Subclass_Comparator(self):
self.mox.StubOutWithMock(
mox_helper.TestClassFromAnotherModule, 'Value')
mox_helper.TestClassFromAnotherModule, 'Value')
mox_helper.TestClassFromAnotherModule.Value(
mox.IsA(mox_helper.ChildClassFromAnotherModule)).AndReturn('foo')
mox.IsA(mox_helper.ChildClassFromAnotherModule)).AndReturn('foo')
self.mox.ReplayAll()
instance = mox_helper.ChildClassFromAnotherModule()
@ -1760,7 +1773,7 @@ class MoxTest(unittest.TestCase):
# This should fail, since the instances are different
self.assertRaises(mox.UnexpectedMethodCallError,
TestClass.OtherValidCall, "wrong self")
TestClass.OtherValidCall, "wrong self")
self.mox.VerifyAll()
self.mox.UnsetStubs()
@ -1848,7 +1861,7 @@ class MoxTest(unittest.TestCase):
self.mox.UnsetStubs()
def testStubOutMethod_Func_PropgatesExceptions(self):
"""Errors in a Func comparator should propagate to the calling method."""
"""Errors in Func comparator should propagate to the calling method."""
class TestException(Exception):
pass
@ -1861,14 +1874,14 @@ class MoxTest(unittest.TestCase):
test_obj = TestClass()
self.mox.StubOutWithMock(test_obj, 'MethodWithArgs')
test_obj.MethodWithArgs(
mox.IgnoreArg(), mox.Func(raiseExceptionOnNotOne)).AndReturn(1)
mox.IgnoreArg(), mox.Func(raiseExceptionOnNotOne)).AndReturn(1)
test_obj.MethodWithArgs(
mox.IgnoreArg(), mox.Func(raiseExceptionOnNotOne)).AndReturn(1)
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)
test_obj.MethodWithArgs, 'ignored', 2)
self.mox.VerifyAll()
self.mox.UnsetStubs()
@ -1889,10 +1902,10 @@ class MoxTest(unittest.TestCase):
"""Test a mocked class whose __init__ returns a Mock."""
self.mox.StubOutWithMock(mox_helper, 'TestClassFromAnotherModule')
self.assertTrue(isinstance(mox_helper.TestClassFromAnotherModule,
mox.MockObject))
mox.MockObject))
mock_instance = self.mox.CreateMock(
mox_helper.TestClassFromAnotherModule)
mox_helper.TestClassFromAnotherModule)
mox_helper.TestClassFromAnotherModule().AndReturn(mock_instance)
mock_instance.Value().AndReturn('mock instance')
@ -1937,7 +1950,7 @@ class MoxTest(unittest.TestCase):
def testStubOutClass_NotAClass(self):
self.assertRaises(TypeError, self.mox.StubOutClassWithMocks,
mox_helper, 'MyTestFunction')
mox_helper, 'MyTestFunction')
def testStubOutClassNotEnoughCreated(self):
self.mox.StubOutClassWithMocks(mox_helper, 'CallableClass')
@ -1966,7 +1979,7 @@ class MoxTest(unittest.TestCase):
self.mox.ReplayAll()
self.assertRaises(mox.UnexpectedMethodCallError,
mox_helper.CallableClass, 8, 9)
mox_helper.CallableClass, 8, 9)
self.mox.UnsetStubs()
def testStubOutClassTooManyCreated(self):
@ -1977,7 +1990,7 @@ class MoxTest(unittest.TestCase):
self.mox.ReplayAll()
mox_helper.CallableClass(1, 2)
self.assertRaises(mox.UnexpectedMockCreationError,
mox_helper.CallableClass, 8, 9)
mox_helper.CallableClass, 8, 9)
self.mox.UnsetStubs()
@ -1985,7 +1998,7 @@ class MoxTest(unittest.TestCase):
"""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')
'MyStaticMethod')
def testStubOutFirstClassMethodVerifiesSignature(self):
self.mox.StubOutWithMock(mox_helper, 'MyTestFunction')
@ -2038,8 +2051,7 @@ class MoxTest(unittest.TestCase):
self.assertFalse(isinstance(foo.obj, mox.MockObject))
def testForgotReplayHelpfulMessage(self):
"""If there is an AttributeError on a MockMethod, give users a helpful msg.
"""
"""If there is an AttributeError on a MockMethod, give helpful msg."""
foo = self.mox.CreateMockAnything()
bar = self.mox.CreateMockAnything()
foo.GetBar().AndReturn(bar)
@ -2048,8 +2060,9 @@ class MoxTest(unittest.TestCase):
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))
self.assertEqual(
'MockMethod has no attribute "ShowMeTheMoney". '
'Did you remember to put your mocks in replay mode?', str(e))
class ReplayTest(unittest.TestCase):
@ -2064,7 +2077,7 @@ class ReplayTest(unittest.TestCase):
class MoxTestBaseTest(unittest.TestCase):
"""Verify that all tests in a class derived from MoxTestBase are wrapped."""
"""Verify that all tests in class derived from MoxTestBase are wrapped."""
def setUp(self):
self.mox = mox.Mox()
@ -2081,8 +2094,8 @@ class MoxTestBaseTest(unittest.TestCase):
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
Assigns a mox.Mox instance as the mox attribute of the test instance.
Replacement Mox instance is under our control before setUp is called
in the test class instance.
"""
self.test.mox = self.test_mox
@ -2119,7 +2132,7 @@ class MoxTestBaseTest(unittest.TestCase):
self._VerifySuccess()
def testSuccessNoMocks(self):
"""Let testSuccess() unset all the mocks, and verify they've been unset."""
"""testSuccess() unsets all the mocks. Vverify they've been unset."""
self._CreateTest('testSuccess')
self.test.run(result=self.result)
self.assertTrue(self.result.wasSuccessful())
@ -2199,7 +2212,7 @@ class MoxTestBaseTest(unittest.TestCase):
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.
Ensures metaclass properly wrapped test methods from all base classes.
If unsetting of stubs doesn't happen, this will fail.
"""
self._CreateTest('testStatOther')
@ -2212,7 +2225,7 @@ class VerifyTest(unittest.TestCase):
def testVerify(self):
"""Verify should be called for all objects.
This should throw an exception because the expected behavior did not occur.
Should throw an exception because the expected behavior did not occur.
"""
mock_obj = mox.MockObject(TestClass)
mock_obj.ValidCall()
@ -2275,11 +2288,11 @@ class MoxTestDontMockProperties(MoxTestBaseTest):
def testPropertiesArentMocked(self):
mock_class = self.mox.CreateMock(ClassWithProperties)
self.assertRaises(mox.UnknownMethodCallError,
lambda: mock_class.prop_attr)
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"
@ -2376,7 +2389,7 @@ class SubscribtableNonIterableClass(object):
class InheritsFromCallable(CallableClass):
"""This class should also be mockable; it inherits from a callable class."""
"""This class should be mockable; it inherits from a callable class."""
pass

View File

@ -19,7 +19,7 @@ import unittest
from mox3 import mox
from mox3 import stubout
from . import stubout_helper
from mox3.tests import stubout_helper
class StubOutForTestingTest(unittest.TestCase):

View File

@ -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)

View File

@ -22,6 +22,5 @@ commands =
[flake8]
show-source = true
ignore = H
builtins = _
exclude=.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg