MarAja
MarAja

Reputation: 1597

How to compare two lists of objects with an assert using unittest module in Python?

I have a method that returns a list of objects of a certain class (let's call that class A with attributes a,b c and the method my_method. So I get something like:

my_method() -> [A(a1, b1, c1), A(a2, b2, c2), A(a3, b3, c3)]

I want to unittest this method but I don't really know which assertion method I should use to do so.

I would like to write something like:

self.assertListEqual(my_method(), [A(a1, b1, c1), A(a2, b2, c2), A(a3, b3, c3)])

Notice, this line does not work (I get a failure for the test) because I think it does not work with objects list (only with basic type lists like number list). I get a:

First differing element 0

and a detail showing that those first objects have different adresses (which is of course normal) but it is not what I wanna compare. I just want to compare if attributes are equal (FYI, attributes a, b and c are "basic" types that is to say string or numbers)

The order of the elements does not matter. So I want to get a failure only if both lists contains effectively different elements (and not the same in a different order). I am working with Python3.

Thank you,

Upvotes: 4

Views: 11968

Answers (2)

Mahmood R
Mahmood R

Reputation: 56

actual = my_method() 
expected = [A(a1, b1, c1), A(a2, b2, c2), A(a3, b3, c3)]
self.assertListEqual(list(map(vars, expected)), list(map(vars, actual)))

You can apply var to the element of the list. As a side note, the correct order for the arguments of assert() is (expected, actual) and not (actual, expected). The order matters because in case of test failure the error message would be wrong if the order was wrong.

Upvotes: 3

Jakub P.
Jakub P.

Reputation: 6046

I'm not sure how to scalably implement eq but you could simply try this:

import unittest

class A:
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def __eq__(self, other):
        return self.a == other.a and self.b == other.b and self.c == other.c


a1, a2, a3 = ('a1', 'a2', 'a3')
b1, b2, b3 = ('b1', 'b2', 'b3')
c1, c2, c3 = ('c1', 'c2', 'c3')

def my_method():
    return [
        A(a1, b1, c1),
        A(a2, b2, c2),
        A(a3, b3, c3)
    ]

class BasicsTestCase(unittest.TestCase):
    def test_list_of_objects(self):
        self.assertListEqual(my_method(), [A(a1, b1, c1), A(a2, b2, c2),  A(a3, b3, c3)])

However I'm not sure it's easy to parse the result if there's an actual error in my_method(), so that's just a quick and dirty solution...

Upvotes: 5

Related Questions