How to stub this class?

63 views
Skip to first unread message

unread,
May 21, 2009, 8:44:07 AM5/21/09
to mox-discuss
Hi.

I'm comparing mock frameworks for my projects and found mox very
interesting.

But there is a point that I didn't understand: how to stub a class.
Here is my code:

Code to test:

...
import xmpp
jid = xmpp.protocol.JID('na...@jabber.localdomain/python')
...
JID is a class that receive args on contructor.

Now I'm trying to stub this class:

import xmpp
import mox
...
m = mox.Mox()
m.StubOutWithMock(xmpp.protocol, "JID")
jid = xmpp.protocol.JID('na...@jabber.localdomain/python')

TypeError: Not callable

Another test:

m.StubOutWithMock(xmpp.protocol.JID, "__init__")
jid = xmpp.protocol.JID('na...@jabber.localdomain/python')

TypeError: Not callable

What I'm doing wrong?

Thanks!

David Lazăr

unread,
May 22, 2009, 4:12:37 AM5/22/09
to mox-d...@googlegroups.com
Hi,

On Thu, May 21, 2009 at 14:44, Zé <jose....@gmail.com> wrote:
> ...
> import xmpp
> jid = xmpp.protocol.JID('na...@jabber.localdomain/python')
> ...
> JID is a class that receive args on contructor.
>
> Now I'm trying to stub this class:
>
> import xmpp
> import mox
> ...
> m = mox.Mox()
> m.StubOutWithMock(xmpp.protocol, "JID")
> jid = xmpp.protocol.JID('na...@jabber.localdomain/python')
>
> TypeError: Not callable

Did you call m.ReplayAll() after setting up the mocks and before calling
the code under test?

-=[david]=-

unread,
May 22, 2009, 8:54:08 AM5/22/09
to mox-discuss
Actually I got this message setting mox.

xmpp.protocol.JID the class that I want to stub. This class receives
one string on constructor.

What I want: StubOut xmpp.protocol.JID with a mock. But instead of
stub with a class, mox is stubbing with a object.

Same result:

import mox
import xmpp
m = mox.Mox()
m.StubOutWithMock(xmpp.protocol, "JID")
m.ReplayAll()
jid = xmpp.protocol.JID('us...@jabber.locadomain/python')

TypeError: Not callable


I expected that here I got a Stub like this:

class MyStub:
def __init__(self, *ignorethis, **ignorethistoo)
pass

Or at least a callable stub.

Here a code snippet to test:

import Queue
import mox
m = mox.Mox()
m.StubOutWithMock(Queue, "Queue")
m.ReplayAll()
queue = Queue.Queue(10)

José Arthur.

On May 22, 5:12 am, David Lazăr <dla...@gmail.com> wrote:
> Hi,
>
>
>
> On Thu, May 21, 2009 at 14:44, Zé <jose.art...@gmail.com> wrote:
> > ...
> > import xmpp
> > jid = xmpp.protocol.JID('n...@jabber.localdomain/python')
> > ...
> > JID is a class that receive args on contructor.
>
> > Now I'm trying to stub this class:
>
> > import xmpp
> > import mox
> > ...
> > m = mox.Mox()
> > m.StubOutWithMock(xmpp.protocol, "JID")
> > jid = xmpp.protocol.JID('n...@jabber.localdomain/python')

steve middlekauff

unread,
May 22, 2009, 11:09:03 AM5/22/09
to mox-d...@googlegroups.com
So you are trying to mock out the constructor, of JID, so that when
called it will always return a mock instance?
--
Steve Middlekauff
smid...@gmail.com

unread,
May 22, 2009, 12:13:12 PM5/22/09
to mox-discuss
Yes, that's it!

How can I do it? I'm playing with CreateMockAnything now, but no
progress so far.

José Arthur.

On May 22, 12:09 pm, steve middlekauff <smidd...@gmail.com> wrote:
> So you are trying to mock out the constructor, of JID, so that when
> called it will always return a mock instance?
>
>
>
> On Fri, May 22, 2009 at 5:54 AM, Zé <jose.art...@gmail.com> wrote:
>
> > Actually I got this message setting mox.
>
> > xmpp.protocol.JID the class that I want to stub. This class receives
> > one string on constructor.
>
> > What I want: StubOut xmpp.protocol.JID with a mock. But instead of
> > stub with a class, mox is stubbing with a object.
>
> > Same result:
>
> > import mox
> > import xmpp
> > m = mox.Mox()
> > m.StubOutWithMock(xmpp.protocol, "JID")
> > m.ReplayAll()
> > jid = xmpp.protocol.JID('u...@jabber.locadomain/python')
> smidd...@gmail.com

steve middlekauff

unread,
May 22, 2009, 4:21:05 PM5/22/09
to mox-d...@googlegroups.com
I think I just figured out how to do this for the first time myself...
or maybe I've done it before and totally forgot all of the python
voodoo required.

Attached is some sample code that works. It stubs out one of the
classes in a module that comes distributed with mox.
--
Steve Middlekauff
smid...@gmail.com
ctor_stub.py

unread,
May 22, 2009, 5:05:42 PM5/22/09
to mox-discuss
It didn't worked:
-----------
import mox
import xmpp

m = mox.Mox()
m.StubOutWithMock(xmpp.protocol.JID, "__new__",
use_mock_anything=True)

AttributeError: class JID has no attribute '__new__'
-----------
another try:
import mox
import xmpp

m = mox.Mox()
m.StubOutWithMock(xmpp.protocol.JID, "__init__",
use_mock_anything=True)
fake_jid = m.CreateMock(xmpp.protocol.JID)
xmpp.protocol.JID('test').AndReturn(fake_jid)

TypeError: __init__() should return None
-----------

Now, this works but its ugly

import mox
import xmpp

m = mox.Mox()
fake_jid = m.CreateMockAnything()
fake_jid('test').AndReturn(fake_jid)
old_jid = xmpp.protocol.JID
xmpp.protocol.JID = fake_jid
m.ReplayAll()
jid = xmpp.protocol.JID('test')
m.VerifyAll()
xmpp.protocol.JID = old_jid

Any ideas?
> smidd...@gmail.com
>
>  ctor_stub.py
> 1KViewDownload

steve middlekauff

unread,
May 22, 2009, 8:12:15 PM5/22/09
to mox-d...@googlegroups.com
You definitely can't use __init__ for this. __init__ is used to
initialize a constructed instance. __new__ constructs the instance.
I believe that my example will only work for new style classes that
have a zero-arg __init__ method. It's obviously not working for you.
:(

Is JID a native class, like cStringIO, or just an oldstyle class
(doesn't inherit from 'object'?)? I'm not familiar with the library.

I should take a step back and ask:
Are you using dependency injection?
If not, have you considered it?

If so, all you'd need to do is create a mock object of
xmpp.protocol.JID, and pass it in to the code-under-test. It might be
too late to rearchitect your code, but it might not. While tedious at
first, it does make things a lot nicer down the road, for larger
projects.

I don't know if you've tried this, but it might work (I really hope so!)

import mox
import xmpp

m = mox.Mox()
# Do this before you replace JID
fake_jid = m.CreateMock(xmpp.protocol.JID)
m.StubOutWithMock(xmpp.protocol, "JID", use_mock_anything=True)
xmpp.protocol.JID('test').AndReturn(fake_jid)
...
# The rest of your code
--
Steve Middlekauff
smid...@gmail.com

steve middlekauff

unread,
May 22, 2009, 8:15:08 PM5/22/09
to mox-d...@googlegroups.com
Also, this is a really poorly worded/labeled, under-explained example:

http://code.google.com/p/pymox/wiki/MoxDocumentation#Mock_a_module

I'll fix it up when I've got a minute.

I hope this solves your problems. :)
--
Steve Middlekauff
smid...@gmail.com

unread,
May 22, 2009, 10:13:17 PM5/22/09
to mox-discuss
xmpp.protocol.JID is an old style class:

class JID:
""" JID object. JID can be built from string, modified, compared,
serialised into string. """
def __init__(self, jid=None, node='', domain='', resource=''):
...

Well, I don't considered DI yet. My example is a xmpphandler for
logging that I made myself (about 100 lines). What I'm really looking
for is knowledge and good libraries to replicate my experience at
work.

So far I just tested state, not behavior, so I'm playing with stubs
and mocks.

Thanks for the help so far.

José Arthur.
Reply all
Reply to author
Forward
0 new messages