Closed GoogleCodeExporter closed 9 years ago
It's a good idea to combine solution with
http://code.google.com/p/mock/issues/detail?id=137 and name it "class_spec".
Original comment by k...@k-bx.com
on 3 Mar 2012 at 1:45
This is just a bug, it *should* work - and in fact I thought I'd fixed this in
0.8! A fix will be in 0.8.1.
>>> from mock import MagicMock
>>> class A(object): pass
...
>>> m = MagicMock(spec=A)
>>> isinstance(m(), A)
False # --> should return True
Original comment by fuzzyman
on 3 Mar 2012 at 11:42
I came to fix this and realised it isn't a bug but by design.
The idea is that you *should* be able to mock an instance of "A" without
creating an instance - you should able to use "A" as a spec. That means if you
create a mock with "A" as a spec you may intend this to be a mock instance (so
the return value could be anything) or you may intend this to be a mock class
(so the return value is an instance). Mock won't guess for you - you have to be
explicit:
{{{
>>> from mock import MagicMock
>>> class A(object): pass
...
>>> m = MagicMock(spec=A, return_value=MagicMock(spec=A))
>>> isinstance(m, A)
True
>>> isinstance(m(), A)
True
}}}
There is one place where mock *will* guess for you, and this is where you are
using patch to replace a class and you set "spec=True". If the object being
replaced is a class then mock *knows* you are replacing a class, so it will set
the spec on the return value mock for you:
{{{
>>> from mock import patch
>>> class Foo(object): pass
...
>>> FooClass = Foo
>>> with patch('__main__.FooClass', spec=True) as M:
... print isinstance(M, Foo)
... print isinstance(M(), Foo)
...
True
True
}}}
Original comment by fuzzyman
on 8 Mar 2012 at 6:58
Ok, so here you will create an object with spec of class, that doesn't work in
real world (where in __init__ you will do self.a = 'foo'.
Should I create a separate bug report for "going through isinstance without
limiting to spec"? Thanks.
Original comment by k...@k-bx.com
on 12 Mar 2012 at 11:09
The documentation talks about the problems with using a class for a spec where
you have instance attributes that aren't on the class. One of the ways to
solve this is to use class attributes as defaults. Another one is to "set"
instance attributes manually on the mock after creation (perhaps via a helper
function if you have to do it a bunch of times). As a third option you can use
a list of strings as your spec instead of the class object.
If you loosen spec so that it allows you to access any attribute then what is
the point of spec now? (You might as well just use an ordinary mock - spec
*only* limits the available attributes.)
Original comment by fuzzyman
on 12 Mar 2012 at 6:29
> If you loosen spec so that it allows you to access any attribute then what is
the point of spec now?
That's my point too! I don't need spec, I just want isinstance to pass.
Original comment by k...@k-bx.com
on 14 Mar 2012 at 5:13
Original issue reported on code.google.com by
k...@k-bx.com
on 3 Mar 2012 at 1:38