I am enjoying my first experience of testing Python code using mockito
-- so far I have written several thousand lines of code and tests, and
almost everything I wanted to express "just worked".
But now I have found a problem, when I need to mock an object with a
special '__str__()' method. Here is a listing to demonstrate the problem
and the error traceback that I get on executing it.
Is this some fundamental limitation with mockito-python, or the Python
interpreter? Or is there some cunning method of 'escaping' the
method-name so Python does not treat it differently?
I know that I can use a real Python stub object for 'cellpos' instead of
a Mock in my testing, but it seems to me to be cleaner to use Mocks for
everything.
================================================================================
from mockito import *
import unittest
# a CellPos instance
cellpos = Mock()
when(cellpos).__str__().thenReturn("M4")
# the Gnumeric module
Gnumeric = Mock()
when(Gnumeric).CellPos(any(int), any(int)).thenReturn(cellpos)
class TestSomethingUsingCellPos:
def test_something(self):
some_cell_pos = Gnumeric.CellPos(3, 12)
self.assertEqual(str(some_cell_pos), "M4")
if __name__ == "__main__":
unittest.main()
===============================================================================
Traceback (most recent call last):
File "problem_demo.py", line 8, in <module>
when(cellpos).__str__().thenReturn("M4")
AttributeError: 'str' object has no attribute 'thenReturn'
===============================================================================
> It's the limitation of mockito-python. Special class methods, like
> __str__, are not stubbed out
I was afraid of that.
> I'll take a look at what's possible here.
Thank you, but you need not spend too much time on it, as I have a
workaround available. Just a note about the limitation on the
mockito-python documentation page should help others fall into the same
trap that I did.
> On the other hand, I don't see much value in the test that you have
> sent.
Yes, of course! I was trying to save you time by cutting the example
down to the bare minimum to demonstrate the problem.
The real point is that my software under test invokes the str() function
on an external object which is not available in the unittest
environment, so I must provide a substitute object to be called and that
object must have a __str__() method.
Now it seems that I cannot use the oh-so-easy mockito recipe in this
particular case, so I must code a stub object by hand (oh no!) in
Python.
I am still very happy that mockito satisfies over 99% of my needs for
mocks/stubs/etc. and is so easy to learn (whilst learning Python and all
the associated tools at the same time!). Great work, folks!
Thanks for pointing that out, we will add it to the documentation.
> Now it seems that I cannot use the oh-so-easy mockito recipe in this
> particular case, so I must code a stub object by hand (oh no!) in
> Python.
Well, sometimes it's the only way :)
> I am still very happy that mockito satisfies over 99% of my needs for
> mocks/stubs/etc. and is so easy to learn (whilst learning Python and all
> the associated tools at the same time!). Great work, folks!
Thank you!
Best regards,
Bartosz