[TIP] Issue setting up the correct mocking behavior
Michael Foord
fuzzyman at voidspace.org.uk
Tue Apr 17 04:57:26 PDT 2012
On 14 Apr 2012, at 12:41, Jonas Geiregat wrote:
> Hello,
>
> I'm trying to test a function that imports and acts upon a django model.
>
> from apps.market.models import Gig
>
> def create_house(location, date, price):
> house = House(id=None, date, price)
> house.save()
>
> # calculate some stuff and further expand the house instance
> # for example house.tag.add("some-tag")
>
> # save after calculations
> house.save()
>
> I like to mock out the House module.
> This is what I've tried so far, this is a method of a TestCase class:
>
> @patch('apps.market.models.House')
> def create_house_test(self, MockedHouse):
>
> """ Constants """
> DAYS_FROM_TODAY = 55
> DATE = datetime.date.today() + datetime.timedelta(days=DAYS_FROM_TODAY)
> PRICE = 250000
>
> # A location is also a django module , I'm using factory_boy here for building a 'mocked' location
> location = LocationFactory.build()
>
>
> create_house(DATE, PRICE)
> MockedHouse.assert_called_with(None, DATE, PRICE)
> MockedHouse.save.assert_called_with()
>
>
> I keep getting an assertionError, the Class is never called.
>
It looks to me like you're patching the House class in the wrong place. You're patching it where it is defined ('apps.market.models.House') but the code that is *using* the class is in another module - so it has already imported the House class (and got a reference to the real class) before your patch is put in place.
This is the classic problem with patch - you do your patching where objects are *used* (or where they are looked up more specifically) and not where they are defined. See this part of the documentation:
http://www.voidspace.org.uk/python/mock/patch.html#id1
If you're using the House class in a view then your patch should look something like @patch('apps.market.views.House') instead.
> I'm also wondering if it's possible to inspect MockedHouse to see if it has for example some tags added to it.
>
If you want to look at the house *instance*, and see if attributes have been set, then you should be looking at MockedHouse.return_value. When MockedHouse is instantiated it is *called*, so the mock object that is modified is the return value of MockedHouse.
HTH,
Michael Foord
> Any help is appreciated,
>
> Jonas.
>
>
> _______________________________________________
> testing-in-python mailing list
> testing-in-python at lists.idyll.org
> http://lists.idyll.org/listinfo/testing-in-python
>
--
http://www.voidspace.org.uk/
May you do good and not evil
May you find forgiveness for yourself and forgive others
May you share freely, never taking more than you give.
-- the sqlite blessing
http://www.sqlite.org/different.html
More information about the testing-in-python
mailing list