qin / pymox Goto Github PK
View Code? Open in Web Editor NEWAutomatically exported from code.google.com/p/pymox
License: Apache License 2.0
Automatically exported from code.google.com/p/pymox
License: Apache License 2.0
Currently the following works:
-----
m = mox.Mox()
obj = m.CreateMockAnything()
m.ReplayAll()
print obj.f
-----
This hides many bugs when doing unit testing, because attribute accesses to
'forbidden' or nonexistent attributes is not spotted.
As to the obvious solution of using CreateMock() instead of
CreateMockAnything(), it's not applicable in some cases, like unit-testing a
piece of code before the objects with which it interacts have been developed.
My suggestion is to cause such attribute access fail with
UnexpectedAttributeAccess exception or something similar. Of course this will
slightly modify the current behavior, according to which the exception is only
thrown when 'f' gets called.
Original issue reported on code.google.com by [email protected]
on 4 Jul 2010 at 2:15
What steps will reproduce the problem?
class Foo:
def __str__(self):
print "Foo!"
class TestSuite(unittest.TestCase):
def setUp(self):
self.m = mox.Mox()
def tearDown(self):
self.m.UnsetStubs()
def test_Foo_str(self):
f = self.m.CreateMock(Foo)
self.m.ReplayAll()
res = str(f) # res receives '<MockAnything instance at xx>'
self.m.VerifyAll()
What is the expected output? What do you see instead?
In most situations, MockObject.__str__ is useful but in some, it prevents from
testing a class's __str__ method. Instead of receiving '<MockAnything...>' in
the example above, there should be a way to make it receive "Foo!"
What version of the product are you using? On what operating system?
0.5.3
Debian GNU/Linux
Please provide any additional information below.
A short discussion was held about this subject on the mailing list[1] and it
was suggested that some mechanism could disable MockObject's additional methods.
[1]:http://groups.google.com/group/mox-discuss/browse_thread/thread/72c214e943a3
ec16
Original issue reported on code.google.com by [email protected]
on 27 Sep 2010 at 6:34
What steps will reproduce the problem?
Record an expectation, where a mock is passed as argument to a method of
another mock. This expectation will be fulfilled, even if another mock-instance
is actually passed, as long as this is of the same type. Example code is
attached.
What is the expected output? What do you see instead?
Expectation should fails. Testing for object identity in __equals__ would
achieve this.
What version of the product are you using? On what operating system?
pymox 0.5.3, windows 7 64 bit, jython 2.5.2rc3
Please provide any additional information below.
Original issue reported on code.google.com by [email protected]
on 2 Mar 2011 at 10:41
Attachments:
Tested againt latest trunk (rev. 38)
I've encountered one bad issue in mock: it can sometimes happen that an
error is silently "swallowed" by the mocking framework. (see the attached
file).
Basically, what happens is that MockMethod just raises an exception
immediately if the method is called unexpectedly. But if the exception is
trapped in the caller code, e.g. something like
try:
mockobject.callUnknownMethod()
except:
log.error.something(....)
the exception is swallowed and the test passes without error.
Of course, the try...except in the caller code might be perfectly legit
(because there might be the absolute need the func not to throw at
anytime), but it is aimed at catching exceptions which are raised by the
function call itself, not by the fact that the function should not be called.
I do not provide a patch since I think this would need a bit of "rework",
e.g. a MockMethod raising such error should trigger a change in the
"global" Mox object state which should then be re-raised when calling
VerifyAll().
Original issue reported on code.google.com by [email protected]
on 21 Dec 2009 at 3:38
Attachments:
What steps will reproduce the problem?
1. Use the In() comparator with a tuple (In((1, 2, 3)) so that you're
matching a function call with something that contains a tuple
2. Fail the call check
What is the expected output? What do you see instead?
pymox should give a proper error how the call signature did not match but
instead it fails with this:
mox/mox.py", line 1400, in __repr__
return '<sequence or map containing \'%s\'>' % self._key
What version of the product are you using? On what operating system?
0.5.0 (I browsed the SVN source and seems to have the issue). Linux based
OS.
Please provide any additional information below.
The problem is obvious, if self._key happens to be a tuple Python will try
to perform multiple substitutions which is not the case. So the above code
should wrap the user value like: str(self._key) and then this issue is
gone. I haven't checked all the other comparators but it's theoretically
possible for this to happen in any comparator where a %s substitution is
tried for a user given input (which can be a tuple).
Original issue reported on code.google.com by [email protected]
on 5 Jun 2010 at 12:20
The only version available for easy_install is mox 0.5.0 which however still
has the bug mentioned in Issue 8
http://code.google.com/p/pymox/issues/detail?id=8
Original issue reported on code.google.com by [email protected]
on 13 Aug 2010 at 10:55
What steps will reproduce the problem?
import mox
print mox.SameElementsAs([1,2,3])
What is the expected output? What do you see instead?
<sequence with same elements as '1,2,3'>
AttributeError
What version of the product are you using? On what operating system?
in trunk
Please provide any additional information below.
__repr__ should use self._expected_list not self._expected_seq
Original issue reported on code.google.com by [email protected]
on 20 Sep 2010 at 9:23
Would be nice when testing objects that have __eq__/__cmp__ logic that might
create false positives or true negatives.
Suggested patch included:
-----------8< ------- 8< ---------
diff --git a/mox.py b/mox.py
index ba73bd3..dd66f3b 100755
--- a/mox.py
+++ b/mox.py
@@ -1220,6 +1220,13 @@ class Comparator:
def __ne__(self, rhs):
return not self.equals(rhs)
+class Is(Comparator):
+ def __init__(self, obj):
+ self._obj = obj
+ def equals(self, rhs):
+ return rhs is self._obj
+ def __repr__(self):
+ return "<is %r (%s)>" % (self._obj, id(self._obj))
class IsA(Comparator):
"""This class wraps a basic Python type or class. It is used to verify
diff --git a/mox_test.py b/mox_test.py
index 2e429e6..f1c4b56 100755
--- a/mox_test.py
+++ b/mox_test.py
@@ -259,6 +259,51 @@ class RegexTest(unittest.TestCase):
"<regular expression 'a\s+b', flags=4>")
+class IsTest(unittest.TestCase):
+ """Verify Is correctly checks equality based upon identity, not value"""
+
+ class AlwaysComparesTrue(object):
+ def __eq__(self, other):
+ return True
+ def __cmp__(self, other):
+ return 0
+ def __ne__(self, other):
+ return False
+
+ 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 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 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)
+
class IsATest(unittest.TestCase):
"""Verify IsA correctly checks equality based upon class type, not value."""
Original issue reported on code.google.com by [email protected]
on 23 Jun 2010 at 11:50
There is a tarball up on googlecode labeled 0.5.3. There is also one on PyPI.
They have different contents. Fedora packages are using the one from PyPI and
Ubuntu is using the one from googlecode. In at least one scenario, we hit
OpenStack test cases which passed on Ubuntu (erroneously) and failed on Fedora
(correctly) - so it seems like the PyPI version may be "more" correct?
In any case - would it be possible to just go ahead and cut an 0.5.4 based on
where things are at now and upload it to both googlecode and PyPI? Having two
things with the same name is ... well, I'm sure OpenStack won't be the other
set of folks to hit confusion. :)
Original issue reported on code.google.com by [email protected]
on 16 Sep 2011 at 4:45
[this is a feature request]
I recently wrote a small helper class to allow a context handlers to provide
verification. e.g.
def testFoo(self):
# set expectations
with Verification(self.mox):
# call code, assert results.
The implementation is simple:
class Verification(object):
def __init__(self, m):
self.m = m
def __enter__(self):
self.m.ReplayAll()
def __exit__(self, exc_type, exc_value, traceback):
if exc_type is None and exc_value is None and traceback is None:
self.m.VerifyAll()
I think that this should probably be a core part of mox, allowing one to say:
def testFoo(self):
with self.mox.Verification():
# …
To my eye, this nicely delineates the code under test from the setup code.
I've attached a sample implementation for discussion. Some points from that:
- I'm not sure what the minimum Python version of pymox is. Context handlers
are a 2.6ism.
- I placed a function on the Mox class, which uses another class, Verification.
This seemed more flexible than just saying "with self.mox" as it allows for
other context handlers if necessary.
Original issue reported on code.google.com by [email protected]
on 30 Jul 2012 at 8:46
Attachments:
What steps will reproduce the problem?
1. create a class A that defines __contains__
2. create a class B that inherits from A but does not override __contains__
3. try to write a test and stub out __contains__ for the instance of B
You will get a TypeError raised because of current implementation __contains__
lookup:
...
contains = self._class_to_mock.__dict__.get('__contains__', None)
if contains is None:
raise TypeError('unsubscriptable object')
...
What is the expected output? What do you see instead?
The __contains__ should be properly stubbed out in class B object instance
What version of the product are you using? On what operating system?
Python 2.7.2
Windows
Original issue reported on code.google.com by [email protected]
on 3 Sep 2011 at 1:01
Given the object:
class Foo(object):
def bar(one, two, three=None):
pass
When recording or replaying a MockObject(Foo)
m_foo = mox.MockObject(Foo)
# should be recorded in the same for both calls.
m_foo.bar(1, 2, 3)
m_foo.bar(1, 2, three=3)
And verify should work for either:
m_foo.bar(1, 2, 3)
m_foo.bar(1, 2, 3)
... or ...
m_foo.bar(1, 2, three=3)
m_foo.bar(1, 2, three=3)
... or any combination thereof ...
This would require inspecting the method signature, and properly mapping
keyword args, where appropriate. I'm not sure if this is possible or not,
but I'd like to hope so.
What is the expected output? What do you see instead?
See above.
Original issue reported on code.google.com by [email protected]
on 25 Sep 2009 at 8:28
What steps will reproduce the problem?
import unittest
import mox
class Foo(object):
def a(self, a, b):
pass
def b(self, a, b):
pass
class TestFoo(unittest.TestCase):
def setUp(self):
self.mox = mox.Mox()
def test_in_any_order_missing_calls(self):
a = self.mox.CreateMock(Foo)
a.a(a=1, b=2).InAnyOrder("foo")
a.a(a=1, b=2).InAnyOrder("foo")
a.b(a=1, b=2).InAnyOrder("foo")
self.mox.ReplayAll()
a.a(a=1, b=2)
self.mox.VerifyAll()
def test_in_any_order_bad_call(self):
a = self.mox.CreateMock(Foo)
a.a(a=1, b=2).InAnyOrder("foo")
a.a(a=1, b=2).InAnyOrder("foo")
a.b(a=1, b=2).InAnyOrder("foo")
self.mox.ReplayAll()
a.a(a=1, b=2)
a.a(a=2, b=2)
self.mox.VerifyAll()
What is the expected output? What do you see instead?
Output as following (running in nosetests):
======================================================================
FAIL: test_in_any_order_bad_call (foo.TestFoo)
----------------------------------------------------------------------
Traceback (most recent call last):
File ".../foo.py", line 46, in test_in_any_order_bad_call
a.a(a=2, b=2)
File ".../mox.py", line 983, in __call__
expected_method = self._VerifyMethodCall()
File ".../mox.py", line 1035, in _VerifyMethodCall
expected, method = expected.MethodCalled(self)
File ".../mox.py", line 1752, in MethodCalled
raise UnexpectedMethodCallError(mock_method, self)
UnexpectedMethodCallError: Unexpected method call. unexpected:-
expected:+
- Foo.a(a=2, b=2) -> None
+ <UnorderedGroup "foo">
======================================================================
FAIL: test_in_any_order_missing_calls (foo.TestFoo)
----------------------------------------------------------------------
Traceback (most recent call last):
File ".../foo.py", line 36, in test_in_any_order_missing_calls
self.mox.VerifyAll()
File ".../mox.py", line 284, in VerifyAll
mock_obj._Verify()
File ".../mox.py", line 504, in _Verify
raise ExpectedMethodCallsError(self._expected_calls_queue)
ExpectedMethodCallsError: Verify: Expected methods never called:
0. <UnorderedGroup "foo">
----------------------------------------------------------------------
The Problem with the above is that in the first case the unexpected method
call's expected method call is obscured by the UnorderedGroup
representation.
The problem in the second case is that it's not obvious which calls are
missing.
The following is from a patched version of pymox:
======================================================================
FAIL: test_in_any_order_bad_call (foo.TestFoo)
----------------------------------------------------------------------
Traceback (most recent call last):
File ".../foo.py", line 46, in test_in_any_order_bad_call
a.a(a=2, b=2)
File ".../mox.py", line 983, in __call__
expected_method = self._VerifyMethodCall()
File ".../mox.py", line 1035, in _VerifyMethodCall
expected, method = expected.MethodCalled(self)
File ".../mox.py", line 1756, in MethodCalled
raise UnexpectedMethodCallError(mock_method, self)
UnexpectedMethodCallError: Unexpected method call. unexpected:-
expected:+
+ UnorderedGroup "foo" pending calls:
- Foo.a(a=2, b=2) -> None
? ^
+ Foo.a(a=1, b=2) -> None
? ^ +
+ Foo.b(a=1, b=2) -> None
======================================================================
FAIL: test_in_any_order_missing_calls (foo.TestFoo)
----------------------------------------------------------------------
Traceback (most recent call last):
File ".../foo.py", line 36, in test_in_any_order_missing_calls
self.mox.VerifyAll()
File ".../mox.py", line 284, in VerifyAll
mock_obj._Verify()
File ".../mox.py", line 504, in _Verify
raise ExpectedMethodCallsError(self._expected_calls_queue)
ExpectedMethodCallsError: Verify: Expected methods never called:
0. UnorderedGroup "foo" pending calls:
Foo.a(a=1, b=2) -> None
Foo.b(a=1, b=2) -> None
----------------------------------------------------------------------
What version of the product are you using? On what operating system?
SVN trunk r47 (0.5.3 being the latest release prior)
Please provide any additional information below.
I've patched pymox to:
a) Remove spurious newlines in the difflib output from unexpected method
calls.
b) Display the pending method calls in an UnorderedGroup object via
__repr__.
Both changes are included in the attached patch.
Original issue reported on code.google.com by [email protected]
on 11 May 2010 at 6:29
Attachments:
What steps will reproduce the problem?
1. make a test with mox.Func(myfunc)
2. put a bug into myfunc that raises an exception
3. run your test
What is the expected output?
a report of the exception raised
What do you see instead?
a mismatch
Original issue reported on code.google.com by [email protected]
on 19 Apr 2011 at 9:37
At the present time, Mox has one shortcoming: whenever you need to set
attributes on an instance, you need to create the mock object and then set
attributes on it.
This is often the case for attributes that are usually set in the object's
__init__ method and can't be easily inferred by CreateMock, e.g.
class MyClass(object):
def __init__(self):
self.a = 1
# you must mock it this way:
m = Mox()
mockobj = m.CreateMock(MyClass)
mockobj.a = 1
even though this is usually done in setUp(), it might get boring and make
unit tests less and less readable.
This patch lets arbitrary kw args to be supplied to createmock, e.g.
mockobj = m.CreateMock(MyClass, a=1)
self.assertEquals(1, mockobj.a)
This makes it easy to both add instance attributes and to change instance
attribute values from the default (class defined) value.
Original issue reported on code.google.com by [email protected]
on 11 Dec 2009 at 1:48
Attachments:
Related to issue 12, I want to stub out a function with optional arguments. I
can't know in advance whether the optional arguments will be provided or not.
IgnoreArg() is no help with missing arguments.
def bar(one, two=None):
pass
The test subject may call
bar(1)
or
bar(1, two=None)
or
bar(1, None)
or
bar(1, 42)
I'd like to be able to do
bar(1, two=IgnoreArg())
and have it match all of the above.
Original issue reported on code.google.com by stefano.rivera
on 16 Aug 2011 at 9:12
It would be great to have a python 3 compatible version of pymox.
Original issue reported on code.google.com by lamvak
on 28 Mar 2012 at 6:45
What steps will reproduce the problem?
1. Create a test with e.g.
self.mox = mox.Mox()
self.mox.StubOutWithMock(module_under_test.logging, 'info')
...
# other code that doesn't use module.logging
...
self.mox.UnsetStubs()
2. Run the test
What is the expected output? What do you see instead?
I would expect the UnsetStubs call (probably in a tearDown method or
similar) to return module_under_test.logging to its original state.
Instead, all my other tests start failing.
Inserting the line:
module_under_test.logging.info(mox.IsA(str)
just after StubOutWithMock causes the issue to disappear.
What version of the product are you using? On what operating system?
Please provide any additional information below.
Original issue reported on code.google.com by [email protected]
on 22 Sep 2008 at 3:55
Right now, MoxMetaTestBase eats the init call, so you can't use it with any
other metaclasses.
Original issue reported on code.google.com by [email protected]
on 13 Jan 2012 at 10:15
Attachments:
What steps will reproduce the problem?
1. Use StubOutWithMock() to mock a module in 3 separate tests.
What is the expected output?
All tests to pass
What do you see instead?
Traceback (most recent call last):
File
"/local/packages/eclipse-3.4/plugins/org.python.pydev.debug_1.3.18/pysrc/pydevd.
py",
line 583, in trace_dispatch
filename, base = pydevd_file_utils.GetFilenameAndBase(frame)
File
"/local/packages/eclipse-3.4/plugins/org.python.pydev.debug_1.3.18/pysrc/pydevd_
file_utils.py",
line 141, in GetFilenameAndBase
filename = _NormFile(f)
File
"/local/packages/eclipse-3.4/plugins/org.python.pydev.debug_1.3.18/pysrc/pydevd_
file_utils.py",
line 73, in _NormFile
rPath = os.path.abspath
File "/local/devel/PhotoMap2/test/mox.py", line 414, in __getattr__
Traceback (most recent call last):
File
"/local/packages/eclipse-3.4/plugins/org.python.pydev.debug_1.3.18/pysrc/pydevd.
py",
line 852, in <module>
debugger.run(setup['file'], None, None)
File
"/local/packages/eclipse-3.4/plugins/org.python.pydev.debug_1.3.18/pysrc/pydevd.
py",
line 689, in run
execfile(file, globals, locals) #execute the script
File
"/local/packages/eclipse-3.4/plugins/org.python.pydev.debug_1.3.18/pysrc/runfile
s.py",
line 246, in <module>
PydevTestRunner(dirs, test_filter, verbosity).run_tests()
File
"/local/packages/eclipse-3.4/plugins/org.python.pydev.debug_1.3.18/pysrc/runfile
s.py",
line 238, in run_tests
runner.run(unittest.TestSuite(all_tests))
File "/usr/lib64/python2.5/unittest.py", line 705, in run
test(result)
File "/usr/lib64/python2.5/unittest.py", line 437, in __call__
return self.run(*args, **kwds)
File "/usr/lib64/python2.5/unittest.py", line 433, in run
test(result)
File "/usr/lib64/python2.5/unittest.py", line 437, in __call__
return self.run(*args, **kwds)
File "/usr/lib64/python2.5/unittest.py", line 433, in run
test(result)
File "/usr/lib64/python2.5/unittest.py", line 437, in __call__
return self.run(*args, **kwds)
File "/usr/lib64/python2.5/unittest.py", line 433, in run
test(result)
File "/usr/lib64/python2.5/unittest.py", line 281, in __call__
return self.run(*args, **kwds)
File "/usr/lib64/python2.5/unittest.py", line 263, in run
result.addFailure(self, self._exc_info())
File "/usr/lib64/python2.5/unittest.py", line 667, in addFailure
TestResult.addFailure(self, test, err)
File "/usr/lib64/python2.5/unittest.py", line 129, in addFailure
self.failures.append((test, self._exc_info_to_string(err, test)))
File "/usr/lib64/python2.5/unittest.py", line 153, in _exc_info_to_string
return ''.join(traceback.format_exception(exctype, value, tb))
File "/usr/lib64/python2.5/traceback.py", line 131, in format_exception
def format_exception(etype, value, tb, limit = None):
File
"/local/packages/eclipse-3.4/plugins/org.python.pydev.debug_1.3.18/pysrc/pydevd.
py",
line 615, in trace_dispatch
traceback.print_exc()
File "/usr/lib64/python2.5/traceback.py", line 227, in print_exc
print_exception(etype, value, tb, limit, file)
File "/usr/lib64/python2.5/traceback.py", line 125, in print_exception
print_tb(tb, limit, file)
File "/usr/lib64/python2.5/traceback.py", line 69, in print_tb
line = linecache.getline(filename, lineno, f.f_globals)
File "/usr/lib64/python2.5/linecache.py", line 14, in getline
lines = getlines(filename, module_globals)
File "/usr/lib64/python2.5/linecache.py", line 40, in getlines
return updatecache(filename, module_globals)
File "/usr/lib64/python2.5/linecache.py", line 82, in updatecache
basename = os.path.split(filename)[1]
File "/local/devel/PhotoMap2/src/mox.py", line 414, in __getattr__
raise UnknownMethodCallError(name)
mox.UnknownMethodCallError: Method called is not a member of the object: split
What version of the product are you using? On what operating system?
Mox 0.5.0. On Fedora 9 x86_64
Please provide any additional information below.
Original issue reported on code.google.com by [email protected]
on 25 Sep 2008 at 7:26
Attachments:
If I have a class
class Foo(object):
def bar(a):
pass
Then the following should fail
m_foo = mox.MockObject(Foo)
m_foo.bar(1, 2)
because the number of arguments doesn't match the acutal implementations
restrictions.
This will allow tests to fail if the API that they are testing changes from
beneath them.
Original issue reported on code.google.com by [email protected]
on 12 Oct 2011 at 6:16
When trying to use MockAnything in a recorded method call, failures will be
unprintable because MockAnything will record the __repr__ call and raise an
exception.
Using this test code:
mock = mox.Mox ()
mock_qs = mock.CreateMockAnything ()
mock_qs.all ().AndReturn (mock_qs)
mock.ReplayAll ()
mock.VerifyAll ()
Causes this (rather unhelpful) failure:
Traceback (most recent call last):
File "tests/test_gallery.py", line 47, in test_already_contains
mock.VerifyAll ()
File "/usr/lib/python2.5/site-packages/mox-0.5.0-py2.5.egg/mox.py", line
197, in VerifyAll
mock_obj._Verify()
File "/usr/lib/python2.5/site-packages/mox-0.5.0-py2.5.egg/mox.py", line
344, in _Verify
raise ExpectedMethodCallsError(self._expected_calls_queue)
ExpectedMethodCallsError: <unprintable ExpectedMethodCallsError object>
Original issue reported on code.google.com by [email protected]
on 4 Oct 2008 at 5:06
I've been using code like this to do it. I'm happy to contribute a patch
if you agree this is useful and isn't dangerous for some reason that I'm
not seeing:
def StubOutIfNeeded(mox_obj, parent_object, attribute):
"""Stubs out the call only if it's not already a mock."""
if not isinstance(getattr(parent_object, attribute),
(mox.MockAnything, mox.MockObject)):
mox_obj.StubOutWithMock(parent_object, attribute)
Then if I want to set multiple expectations on the thing that I'm stubbing
out, I can safely call StubOutIfNeeded(self.mox, module, 'FunctionName')
each time before setting an expectation, and not worry about whether it's
already been stubbed out or not.
Combined with using mox.MoxTestBase which will unset all stubs in self.mox,
this seems pretty safe, because things will succeed whether I create and
use the stub or don't.
Original issue reported on code.google.com by [email protected]
on 29 May 2009 at 5:30
http://code.google.com/p/pymox/source/detail?spec=svn71&r=71
This documentation change does not seem to be coherent with the newest source
version.
See Mox.StubOutWithMock.
Original issue reported on code.google.com by lamvak
on 26 Mar 2012 at 4:59
Hello,
while using some classes from some external libraries, i realized that if the
parent class uses
zope.interface classProvides and the child does not, I get an AttributeError
while trying to use it
with CreateMock()
this happens because a "rogue" class attribute persists in the class dir()
output (as it is inherited
by the parent class), but it raises AttributeError whenever it is called on the
child class.
A small example which employs a metaclass is attached, so you don't need
installing
zope.interface if you don't want to.
This happens because Mox uses dir() and then something like
getattr(class_to_mock, method),
which breaks in the event an AttributeError is raised. But raising
AttributeError is *the* right way
to do this in python, if you just want customize your object behaviour.
IMHO just using the failsafe getattr(class_to_mock, method, NO_ATTR) signature
is the best
choice; it will break if other errors are raised, just trapping AttributeError.
Of course, in such a
case, the mocked object should NOT expose such attribute.
a patch, with tests, is attached.
Original issue reported on code.google.com by [email protected]
on 10 Oct 2009 at 3:04
Attachments:
What steps will reproduce the problem?
1. mox the time.localtime()
2. call time.localtime() in an other moudle
code:
0 ....
1 t = time.gmtime(time.mktime((2012, 10, 1, 15, 26,0,0,0,0)))
2 self.mox.StubOutWithMock?(time, 'localtime')
3 time.localtime().AndReturn?(t)
4 self.mox.ReplayAll()
5 print "mox localtime:", time.localtime() # correct
6 othermoudle.func() # call time.localtime() in func() # error
7 ...
What is the expected output? What do you see instead?
on the line 5,I got a correct mox time:
(Pdb) time.localtime()
time.struct_time(tm_year=2012, tm_mon=10, tm_mday=1, tm_hour=7, tm_min=26,
tm_sec=0, tm_wday=0, tm_yday=275, tm_isdst=0)
and then call time.localtime in an other moudle, I got an error:
(Pdb) time.time()
1333178201.334844
(Pdb) time.localtime()
UnexpectedMethodCallError: Unexpected method call Stub for <built-in function
localtime>.call() -> None
(Pdb)
What version of the product are you using? On what operating system?
mox-0.5.3-py2.7.egg
python 2.7
Ubuntu 11.10 desktop
Please provide any additional information below.
my error msg is:
Unit test of worker.
mox localtime: time.struct_time(tm_year=2012, tm_mon=10, tm_mday=1, tm_hour=7,
tm_min=26, tm_sec=0, tm_wday=0, tm_yday=275, tm_isdst=0)
F
======================================================================
FAIL: testIsTimeToWorkFirst (__main__.WorkerTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_worker.py", line 64, in testIsTimeToWorkFirst
ret = w.is_timeto_work()
File "/home/pyw/work/demux/worker/worker.py", line 119, in is_timeto_work
self.update_time()
File "/home/pyw/work/demux/worker/worker.py", line 92, in update_time
localtime = time.localtime()
File "/usr/local/lib/python2.7/dist-packages/mox-0.5.3-py2.7.egg/mox.py", line 1002, in __call__
expected_method = self._VerifyMethodCall()
File "/usr/local/lib/python2.7/dist-packages/mox-0.5.3-py2.7.egg/mox.py", line 1049, in _VerifyMethodCall
expected = self._PopNextMethod()
File "/usr/local/lib/python2.7/dist-packages/mox-0.5.3-py2.7.egg/mox.py", line 1035, in _PopNextMethod
raise UnexpectedMethodCallError(self, None)
UnexpectedMethodCallError: Unexpected method call Stub for <built-in function
localtime>.__call__() -> None
Original issue reported on code.google.com by [email protected]
on 31 Mar 2012 at 7:47
I would like to mock classes with properties, but cannot find any example
for this.
When I try set expectations for a property the framework does not
understand the propery attribute. I then tried to set expectations for the
__get* and __set* method for that property, but still when using the
property from the mock-ed class in another class (the class to be tested)
the type of that property is a 'property' and the getter is never executed.
Do I have to manually bind the ID property of the mock class to the getter
and setter? What is the suggested best practice here?
Thanks!
Original issue reported on code.google.com by [email protected]
on 3 Aug 2009 at 8:25
Similar to Issue 34
This fixed the problems for me:
def __str__(self):
if isinstance(self._previous_exceptions, basestring):
exceptions = self._previous_exceptions
else:
exceptions = "\n".join(["%3d. %s: %s" % (i, e.__class__.__name__, e)
for i, e in enumerate(self._previous_exceptions)])
return "Previous exceptions thrown:\n%s" % (exceptions,)
Original issue reported on code.google.com by [email protected]
on 28 Jul 2012 at 2:26
What steps will reproduce the problem?
1. Stub out a classmethod (method) of a base class (Foo) with one child (Bar)
Note that Bar.method.im_self == Bar at this point
2. Execute stub
3. Unset stubs
4. Check Bar.method.im_self. Note that it is now equivalent to Foo
See attached test case for complete example
What is the expected output? What do you see instead?
Bar.method.im_self should revert to it's original value (e.g. Bar, not Foo)
What version of the product are you using? On what operating system?
mox 0.5, OS X
Original issue reported on code.google.com by [email protected]
on 5 Mar 2009 at 8:11
Attachments:
What steps will reproduce the problem?
1. Stub out __new__ on a class without an explicit __new__ definition when
using Python 2.6
2. Unset stubs
3. Try to instantiate the class again
What is the expected output? What do you see instead?
Everything works as expected except that there is a deprecation warning:
DeprecationWarning: object.__new__() takes no parameters
What version of the product are you using? On what operating system?
Mox 0.50, OS X, but most importantly Python 2.6.2 (or any other 2.6.x)
Please provide any additional information below.
This seems to be another edge case of python weirdness that isn't
explicitly covered by mox. Classes that don't explicitly define __new__
use a special, built-in version defined by python. It doesn't seem to be
possible to recover this version, or at least properly rebind it, when
stubs are unset (or something like that, I don't quite understand the
magic). The result seems to be that __new__ is called for object with all
args intact. As of 2.6 object.__new__ only accepts the cls parameter and
barfs a DeprecationWarning if it gets extra args. While it doesn't
actually break anything the warnings are pretty annoying and presumably it
will become a breaking problem when extra args are truly deprecated.
I've attached a patch that fixes the problem as well as a test script
that demonstrates the issue using both mox and just the generic issue in
python. All the patch does is watch for attempts to stub out __new__ when
the existing implementation is a built-in method. If that's the case it
stubs out __new__ it will unstub with a lambda that calls __new__ on the
parent class without any extra args.
Original issue reported on code.google.com by [email protected]
on 26 May 2009 at 6:18
Attachments:
What steps will reproduce the problem?
1. import stubout into a test module
2. invoke StubOutForTesting.SmartSet
3. run the test
What is the expected output? What do you see instead?
The test should succeed, it fails with a stack trace ending in:
File ".../lib/python2.4/site-packages/stubout.py", line 59, in SmartSet
if (inspect.ismodule(obj) or
NameError: global name 'inspect' is not defined
What version of the product are you using? On what operating system?
0.5.0 on Linux
Please provide any additional information below.
Original issue reported on code.google.com by [email protected]
on 25 Mar 2009 at 9:30
See:
http://stackoverflow.com/questions/6124180/python-nose-tests-actually-the-error-
is-from-mox-print-out-errors-one-character
My Fix:
Adding this line to the top of str method of ExpectedMethodCallsError in mox.py
fixes the problem (or this symptom anyway):
if isinstance(self._expected_methods, str):
self._expected_methods = self._expected_methods.split("\n")
Original issue reported on code.google.com by [email protected]
on 26 May 2011 at 9:01
Hello,
while i like Mox, I've encountered a small issue when testing async twisted
code running trial (the twisted builtin test tool, supporting different
reactors, output, debugging, etc).
Since twisted wraps exceptions into failures, it may happen that, in order:
- VerifyAll() is called in a test method, but a certain expected method is
not called;
- a deferred is returned by the same method;
- the deferred then triggers a callback that calls the expected method:
this is what the trial output look like:
===============================================================================
[ERROR]: test_mox_async.AsyncMoxTestCase.testAsyncMox
Traceback (most recent call last):
File
"/home/alan/Private/Dropbox/code/mox-0.5.1.fixtraceback/test_mox_async.py",
line 24, in testAsyncMox
m.VerifyAll()
File "/home/alan/Private/Dropbox/code/mox-0.5.1.fixtraceback/mox.py",
line 198, in VerifyAll
mock_obj._Verify()
File "/home/alan/Private/Dropbox/code/mox-0.5.1.fixtraceback/mox.py",
line 353, in _Verify
raise ExpectedMethodCallsError(self._expected_calls_queue)
mox.ExpectedMethodCallsError: Verify: Expected methods never called:
The error is raised but, since the call has happened (too late, e.g. after
VerifyAll(), but it has happened), I can't see what the problem really is.
you can see the problem by yourself by running the attached file on a
system with twisted 8.2 installed:
trial test_mox_async.py
This seems to be caused by the fact that the exception instance saves the
call queue and concatenates the string to be shown just when __str__ is
called (and that's too late when using trial and twisted).
The attached patch saves formatted calls on init, preventing further issues.
output on a patched Mox:
===============================================================================
[ERROR]: test_mox_async.AsyncMoxTestCase.testAsyncMox
Traceback (most recent call last):
File
"/home/alan/Private/Dropbox/code/mox-0.5.1.fixtraceback/test_mox_async.py",
line 24, in testAsyncMox
m.VerifyAll()
File "/home/alan/Private/Dropbox/code/mox-0.5.1.fixtraceback/mox.py",
line 198, in VerifyAll
mock_obj._Verify()
File "/home/alan/Private/Dropbox/code/mox-0.5.1.fixtraceback/mox.py",
line 353, in _Verify
raise ExpectedMethodCallsError(self._expected_calls_queue)
mox.ExpectedMethodCallsError: Verify: Expected methods never called:
0. __call__('value') -> None
-------------------------------------------------------------------------------
Ran 1 tests in 0.007s
FAILED (errors=1)
Original issue reported on code.google.com by [email protected]
on 9 Oct 2009 at 4:22
Attachments:
I would really like to have this library as a dependency of my application,
but at the moment it is impossible, because pymox is not on PyPI.
Original issue reported on code.google.com by [email protected]
on 20 Nov 2008 at 3:57
I'm not sure if this is a nose problem or a mox problem; but I thought I would
share it here.
The problem is the readability of the error. The error is being thrown because
the mock isn't matching, which is good. However, the error gives no clue as to
what
failed. In OSX, I have no idea what mock getting the wrong data sent to it.
What steps will reproduce the problem?
1. Create a failing test that use mox
2. Run the tests with nose
What is the expected output? What do you see instead?
I expect to see output like:
======================================================================
FAIL: test_failing_hello (mymodule_test.TestHello)
----------------------------------------------------------------------
Traceback (most recent call last):
File "build/bdist.linux-i686/egg/mox.py", line 1374, in new_method
func(self, *args, **kwargs)
File "/home/pope/Documents/code/gist-74723/mymodule_test.py", line 13, in test_failing_hello
mymodule.hello()
File "/home/pope/Documents/code/gist-74723/mymodule.py", line 6, in hello
return repeater("Hello")
File "build/bdist.linux-i686/egg/mox.py", line 562, in __call__
expected_method = self._VerifyMethodCall()
File "build/bdist.linux-i686/egg/mox.py", line 608, in _VerifyMethodCall
raise UnexpectedMethodCallError(self, expected)
UnexpectedMethodCallError: Unexpected method call: __call__('Hello') -> None.
Expecting: __call__('World') -> 'HelloWorld'
----------------------------------------------------------------------
However, I am seeing this:
======================================================================
ERROR: test_failing_hello (mymodule_test.TestHello)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/pope/Desktop/mox_test/nose-0.10.4-py2.6.egg/nose/case.py", line 131, in run
self.runTest(result)
File "/Users/pope/Desktop/mox_test/nose-0.10.4-py2.6.egg/nose/case.py", line 149, in runTest
test(result)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/unittest.py", line 300, in __call__
return self.run(*args, **kwds)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/unittest.py", line 282, in run
result.addFailure(self, self._exc_info())
File "/Users/pope/Desktop/mox_test/nose-0.10.4-py2.6.egg/nose/proxy.py", line 131, in addFailure
formatted = plugins.formatFailure(self.test, err)
File "/Users/pope/Desktop/mox_test/nose-0.10.4-py2.6.egg/nose/plugins/manager.py", line 81, in __call__
return self.call(*arg, **kw)
File "/Users/pope/Desktop/mox_test/nose-0.10.4-py2.6.egg/nose/plugins/manager.py", line 119, in chain
result = meth(*arg, **kw)
File "/Users/pope/Desktop/mox_test/nose-0.10.4-py2.6.egg/nose/plugins/failuredetail.py", line 40, in formatFailure
tbinfo = inspect_traceback(tb)
File "/Users/pope/Desktop/mox_test/nose-0.10.4-py2.6.egg/nose/inspector.py", line 33, in inspect_traceback
inspect_lines, mark_line = find_inspectable_lines(lines, exc_line)
File "/Users/pope/Desktop/mox_test/nose-0.10.4-py2.6.egg/nose/inspector.py", line 122, in find_inspectable_lines
home = lines[pos]
TypeError: 'NoneType' object is unsubscriptable
----------------------------------------------------------------------
What version of the product are you using? On what operating system?
I'm using Mox 0.5.0, Nose 0.10.4, Python 2.5 and 2.6, Mac OS X 10.5.6 Intel
Please provide any additional information below.
I set up a REALLY dumb test case at http://gist.github.com/74723
Original issue reported on code.google.com by [email protected]
on 6 Mar 2009 at 3:10
It's two years from last release - last file from downloads, which is in turn
pulled by pypi and linux distributions packaging agents - the newest version in
Gentoo is 0.5.3.
Original issue reported on code.google.com by lamvak
on 26 Mar 2012 at 4:55
http://google-styleguide.googlecode.com/svn/trunk/pyguide.html#Default_Argument_
Values
Patch attached.
Original issue reported on code.google.com by [email protected]
on 11 Jan 2011 at 5:03
Attachments:
What steps will reproduce the problem?
Mock a given method that has a long and complex signature, and have the
actual call to the mock not match the recorded call.
mock_my_object = self.mox.CreateMock(MyObject)
mock_my_object.SomeComplexMethod(1, 2, 3, 4, 5, 6).AndReturn(True)
self.mox.ReplayAll()
self.assertTrue(mock_my_object.SomeComplexMethod(1, 2, 3, 4, 5, 6, 7))
What is the expected output? What do you see instead?
I would hope that Mox would more elegantly print where the discrepancy in
the method calls is---e.g., "Unequal number of arguments between recorded
and called method: 1 extra argument provided." for the case above.
Something like this would be nice:
Expected <MyObject mock>.SomeComplexMethod(1, 2, 3, 4, 5, 6)
Actual <MyObject mock>.SomeComplexMethod(1, 2, 3, 4, 5, 6, 7)
Extra parameter /|\
What version of the product are you using? On what operating system?
0.5.0 on Linux.
Please provide any additional information below.
It can be really hard to read the discrepancy reports of the current
version.
Original issue reported on code.google.com by [email protected]
on 9 Mar 2009 at 9:11
What steps will reproduce the problem?
1. Create and run the following script:
#!/usr/bin/python
import unittest
import mox
class Test1(mox.MoxTestBase):
def testOK(self):
self.assertEquals(1, 1)
class Test2(Test1):
def testOK(self):
self.assertEquals(1, 2)
if __name__ == '__main__':
unittest.main()
What is the expected output?
FAIL: testOK (__main__.Test2)
Traceback (most recent call last):
File "./lib/apt_forktracer/tests/test_mox.py", line 28, in testOK
self.assertEquals(1, 2)
AssertionError: 1 != 2
----------------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (failures=1)
What do you see instead?
..
----------------------------------------------------------------------
Ran 2 tests in 0.001s
OK
What version of the product are you using?
0.5.1-1
On what operating system?
Ubuntu
Please provide any additional information below.
If I use plain unittest.TestCase everything works as expected - Test2.testOK
overrides
Test1.testOK and two methods are run: Test1.testOK and Test2.testOK
However when using mox.MoxTestBase, the same Test1.testOK method is run twice!
Once in Test1
context, once in Test2 context.
This is using python 2.5.2
Original issue reported on code.google.com by [email protected]
on 28 Mar 2010 at 2:44
What steps will reproduce the problem?
Given module foo:
class Bar:
def Qux(self):
pass
# test
StubOut(foo.Bar, "Qux")
foo.Bar.Qux(IsA(BarSubclass))
# error, since when doing signature inspection, Bar is not an instance of
BarSubclass.
Using an instance of Bar works just fine, as does IgnoreArg()
The signature matching code needs to be smarter, more specifically when IsA
comparator is used.
What is the expected output? What do you see instead?
What version of the product are you using? On what operating system?
Head.
Please provide any additional information below.
Original issue reported on code.google.com by [email protected]
on 18 Aug 2010 at 9:13
sometimes i really don't want to care about any of the args. afaict the only
way to do this is multiple mox.IgnoreArg() arguments, that's silly. allow
mox.IgnoreArgs() to just ignore all args so we're not testing things we don't
care to test (e.g. how many args are sent to our logging function!)
Original issue reported on code.google.com by [email protected]
on 28 Jun 2010 at 8:03
What steps will reproduce the problem?
>>> import mox
>>> comparator = mox.And(1, mox.IsA(int))
>>> comparator == 1
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "/var/lib/python-support/python2.4/mox.py", line 781, in __eq__
return self.equals(rhs)
File "/var/lib/python-support/python2.4/mox.py", line 1067, in equals
if not comparator.equals(rhs):
AttributeError: 'int' object has no attribute 'equals'
What is the expected output? What do you see instead?
I expect True to be returned, however the AttributeError is raised.
What version of the product are you using? On what operating system?
Unknown, however the trunk version of pymox appears to have this bug in
trunk as of Feb 23rd 2010.
Please provide any additional information below.
By using the == operator instead of the .equals() method (with the expected
value on the lhs), this would make literal values usable. Currently
mox.Func(lambda rhs: literal===rhs) needs to be employed to reach the same
effect.
Comparators define __eq__ to call self.equals, so this should preserve
existing behaviour when comparators are passed to the And() comparator.
Although making this change could affect existing test cases that define a
class that defines an equals method that is not called by an __eq__ method.
Note: the same problem/non-feature affects the Or comparator.
Original issue reported on code.google.com by [email protected]
on 23 Apr 2010 at 5:38
While updating to python 2.7.2rc1 we got the following traceback:
File "/usr/lib/pymodules/python2.7/mox.py", line 256, in CreateMock
new_mock = MockObject(class_to_mock, attrs=attrs)
File "/usr/lib/pymodules/python2.7/mox.py", line 553, in __init__
for method in dir(class_to_mock):
TypeError: __dir__() must return a list, not MockMethod
Original issue reported on code.google.com by [email protected]
on 2 Jun 2011 at 7:35
What steps will reproduce the problem?
1. Use mox.ContainsAttributeValue comparator for a check that would fail
2. Run the test and get error printed
What is the expected output? What do you see instead?
Just like with the other Comparator classes, it should say something that tells
what's wrong. Should contain at least what is checking. Instead it displays a
useless generic Python description of the class instance:
+ function.__call__(<IgnoreArg>, <IgnoreArg>, <mox.ContainsAttributeValue
instance at 0x8bb4b6c>) -> 0
From that message I cannot tell what attribute/value was expected and is
missing.
What version of the product are you using? On what operating system?
Latest SVN has the same problem. Linux.
Original issue reported on code.google.com by [email protected]
on 1 Aug 2011 at 9:30
Typo
Original issue reported on code.google.com by [email protected]
on 16 Aug 2011 at 7:58
Attachments:
When stubbing out instance methods the signature is not verified, since
MockAnything is used.
I attached a suggested patch to both the code itself and to the tests in order
to fix this.
Original issue reported on code.google.com by [email protected]
on 17 Jun 2010 at 7:02
Attachments:
What steps will reproduce the problem?
Create a file foo.py containing the following class definitions:
import abc
class Foo(object):
__metaclass__ = abc.ABCMeta
class Bar(Foo):
pass
Now execute the following:
import foo
import mox
mox.Mox().StubOutClassWithMocks(foo, 'Foo')
What is the expected output?
StubOutClassWithMocks() should not produce any errors.
What do you see instead?
Raises "TypeError: Given attr is not a Class. Use StubOutWithMock."
Reason: type(foo.Foo) is <class 'abc.ABCMeta'>, which doesn't fall into any of
the categories in _USE_MOCK_FACTORY.
Original issue reported on code.google.com by [email protected]
on 12 Apr 2012 at 11:53
What steps will reproduce the problem?
mock.AMethod().AndRaise(StopIteration)
What is the expected output? What do you see instead?
The following error message is printed:
AttributeError: No values given for arguments cell groups
It's not obvious that "cell groups" are the argument names used in the
tested code, and the actual message from mox ends at "arguments". One could
imagine an even more confusing combination.
Using some punctuation would help considerably:
AttributeError: No values given for arguments: cell, groups
This is just one place I've encountered this. There might be more similar
cases in need of improvement.
Original issue reported on code.google.com by [email protected]
on 24 May 2010 at 12:21
Mox should provide a comparator to capture a value for later inspection, like
EasyMock's Capture. The Remember comparator can almost do this, but the value
attribute is non-public.
Original issue reported on code.google.com by [email protected]
on 16 Aug 2012 at 8:26
According to PyPI the most popular Python mocking libraries are mock, Mox and
then MiniMock. Yet the comparison page includes neither mock nor MiniMock!
More up to date comparisons (based on your Mox examples) can be found here:
http://www.voidspace.org.uk/python/mock/compare.html
They include a new library called "flexmock" but unfortunately not yet MiniMock.
Original issue reported on code.google.com by fuzzyman
on 27 Feb 2011 at 5:52
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.