¿Puedo falsificar/simular el tipo de mis objetos simulados en las pruebas unitarias de python?

In my python code I check the type of one of the parameters to make sure it is of the type I expect. For instance:

def myfunction(dbConnection):
    if (type(dbConnection)<>bpgsql.Connection):
        r['error'] += ' invalid database connection'

I want to pass a mock connection for testing purposes. Is there a way to make the mock object pretend to be of the correct type?

preguntado el 01 de julio de 12 a las 14:07

Utiliza la pato escribiendo instead of relying on exact class names. -

So basically the answer is NO, you can't fake your type, instead don't check the type directly, see if it walks like a duck and if it is then it's good enough, right? -

@Ali isinstance(x, Foo) devuelve verdadero si x es un Foo, including if x es una instancia de una subclase de Foo. -

Exactly. You should never compare types directly. Not only does this prevent testing like this, it will cause problems if the same module is imported twice causing different class definitions for the same type that will compare unequal. Also <> is deprecated, use !=. -

@Martijn, it will in old versions of IDLE. This is something that actually happened to me once. -

2 Respuestas

With all due respect, It looks like you guys are not quite right!

I can use duck typing as said, but there is a way to do what I intended to do in the first place:

en http://docs.python.org/dev/library/unittest.mock.html

Mock objects that use a class or an instance as a spec or spec_set are able to pass isintance tests:

>>>
>>> mock = Mock(spec=SomeClass)
>>> isinstance(mock, SomeClass)
True
>>> mock = Mock(spec_set=SomeClass())
>>> isinstance(mock, SomeClass)
True

so my example code would be like:

m = mock.MagicMock(spec=bpgsql.Connection)
isinstance(m, bpgsql.Connection) 

this returns True

All that said, I am not arguing for strict type checking in python, I say if you need to check it you can do it and it works with testing and mocking too.

contestado el 13 de mayo de 19 a las 10:05

Also, sometimes you just don't have control over how another library is doing things. If something external is checking the type, it is probably easiest to just use spec or at least set the mock's __class__ equal to the correct type. - shawnfumo

I tried this for PyCharm's static inspections but to no avail. Seems like it should work though; you can find the bug here: youtrack.jetbrains.com/issue/PY-10477 - jtpereyda

This is more-or-less exactly why you shouldn't enforce strict typechecking! You should remove that line from the code entirely.

If you don't want to do that, write an abstract base class with the properties you want to have (.connect(), .cursor(), ...?) and check isinstance de eso.

También <> has been obsolete for aaages. Use !=.

Respondido 01 Jul 12, 14:07

Thanks, so may I ask what is patch for? I confess that I have not yet undertood what it does, but to me it looks like it impersonates a different class docs.python.org/dev/library/unittest.mock.html#id4 - Ali

100% agree on isinstance() over direct typechecking - tom busby

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.