ADoorMarkedPirate
ADoorMarkedPirate

Reputation: 400

Python Assert NDB Items equal

I'm writing a unit test for a project that checks ndb entities from the database.

The following test

def test_active_chains(self):
    chains = self.user.active_chains()
    self.maxDiff = None
    self.assertItemsEqual(self.convert(self.chains), chains)

Produces the following FAIL

AssertionError: Element counts were not equal:
First has 1, Second has 0:  Chain(key=Key('Chain', 4), active=False, address_1=u'20 St.Saviourgate', address_2=None, chain_id=None, country=None, county=u'North Yorkshire', created=datetime.datetime(2018, 2, 7, 13, 31, 56, 197427), deleted=False, eagle_eye_campaign_id=None, eagle_eye_compaign_channel=None, eagle_eye_drinki_channel=None, eagle_eye_offer_channel=None, geo_location=None, name=u'TestChain1', number_of_venues=0, phone=None, post_code=u'YO1 8NN', test_group=False, town=u'York', users=[Key('User_v2', 2)], uses_codes=False)
First has 1, Second has 0:  Chain(key=Key('Chain', 3), active=False, address_1=u'20 St.Saviourgate', address_2=None, chain_id=None, country=None, county=u'North Yorkshire', created=datetime.datetime(2018, 2, 7, 13, 31, 56, 197553), deleted=False, eagle_eye_campaign_id=None, eagle_eye_compaign_channel=None, eagle_eye_drinki_channel=None, eagle_eye_offer_channel=None, geo_location=None, name=u'TestChain2', number_of_venues=0, phone=None, post_code=u'YO1 8NN', test_group=False, town=u'York', users=[Key('User_v2', 2)], uses_codes=False)
First has 0, Second has 1:  Chain(key=Key('Chain', 3), active=False, address_1=u'20 St.Saviourgate', address_2=None, chain_id=None, country=None, county=u'North Yorkshire', created=datetime.datetime(2018, 2, 7, 13, 31, 56, 197553), deleted=False, eagle_eye_campaign_id=None, eagle_eye_compaign_channel=None, eagle_eye_drinki_channel=None, eagle_eye_offer_channel=None, geo_location=None, name=u'TestChain2', number_of_venues=0, phone=None, post_code=u'YO1 8NN', test_group=False, town=u'York', users=[Key('User_v2', 2)], uses_codes=False)
First has 0, Second has 1:  Chain(key=Key('Chain', 4), active=False, address_1=u'20 St.Saviourgate', address_2=None, chain_id=None, country=None, county=u'North Yorkshire', created=datetime.datetime(2018, 2, 7, 13, 31, 56, 197427), deleted=False, eagle_eye_campaign_id=None, eagle_eye_compaign_channel=None, eagle_eye_drinki_channel=None, eagle_eye_offer_channel=None, geo_location=None, name=u'TestChain1', number_of_venues=0, phone=None, post_code=u'YO1 8NN', test_group=False, town=u'York', users=[Key('User_v2', 2)], uses_codes=False)

One can see that the elements being compared in the assertion are the exact same, so why does the assertion not recognise the elements as equal?

I think it has something to do with the items being fetched from the database and thus stored in different memory locations. Does assertItemsEqual require the same memory location of the models it is comparing?

Note:

I have not included any of the methods of my code (i.e convert() or active_chains()) as I don't think the issue lies in here. I can include if required.

Alternate Solution:

I found a work around by creating the following function

def checkAssertItems(self, item1, item2):
    res = self.assertEqual(len(item1), len(item2))
    if res:
        for i in range(0, len(item1)):
            self.assertEqual(item1[i], item2[i])

and replacing my unit test with

def test_active_chains(self):
    chains = self.user.active_chains()
    self.maxDiff = None
    self.checkAssertItems(self.convert(self.chains), chains)

I am curious to know why I can not compare ndb.Models directly.

Upvotes: 1

Views: 241

Answers (2)

vbraun
vbraun

Reputation: 1987

You can use self.assertEqual(a, b) to compare two ndb.Model instances, it just works.

You can also use self.assertEqual(a, b) to compare two lists. Comparison will be element-wise. So if you have two lists containing ndb.Model in the same order, they will compare equal.

self.assertItemsEqual(a, b) sorts the two lists a, b and then compares them; Unless you define a sort order, the sort order will fall back to order by memory location. Which is probably not what you want.

Upvotes: 0

ADoorMarkedPirate
ADoorMarkedPirate

Reputation: 400

I found a work around by creating the following function

def checkAssertItems(self, item1, item2):
    res = self.assertEqual(len(item1), len(item2))
    if res:
        for i in range(0, len(item1)):
            self.assertEqual(item1[i], item2[i])

and replacing my unit test with

def test_active_chains(self):
    chains = self.user.active_chains()
    self.maxDiff = None
    self.checkAssertItems(self.convert(self.chains), chains)

I am curious to know why I can not compare ndb.Models directly.

Upvotes: 1

Related Questions