[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