Reputation: 400
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
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
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