Can I fake/mock the type of my mock objects in python unittests
Question:
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?
Answers:
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
of that.
Also <>
has been obsolete for aaages. Use !=
.
With all due respect, It looks like you guys are not quite correct!
I can use duck typing as said, but there is a way to do what I intended to do in the first place:
from 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.
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?
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
of that.
Also <>
has been obsolete for aaages. Use !=
.
With all due respect, It looks like you guys are not quite correct!
I can use duck typing as said, but there is a way to do what I intended to do in the first place:
from 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.