Search code examples
pythonunit-testingdictionaryassert

AssertionError when trying to assert return value from two dictionaries with py.test


I'm testing a text-based game I've been making to learn Python. The last few days I have been busy finding a solution for a problem I keep encountering. I have tried multiple test methods, but they all end up giving me the same error.

The problem is the following AssertionError (using py.test):

 E       AssertionError: assert <Textgame.Waffle.WineFields object at 0x03BDECD0> == 
 <Textgame.Waffle.WineFields object at 0x03BD00D0>

Obviously, the object (Textgame.Waffle.WineFields) is correct, but the location is different. I don't care about the location. I assume this is because I'm using two separate dictionaries with the same contents. However, I would prefer to keep using this dictionary if possible.

The minimal working example of the test looks as follows:

import Textgame.Waffle

def test_change_map():

    roomnames = {
        "the wine fields" : Textgame.Waffle.WineFields(),
    }

    room = "the wine fields"
    next_room = roomnames[room]

    assert Textgame.Waffle.Map(room).change(room) == next_room

The Textgame.Waffle game I'm trying to assert looks like this:

class WineFields(object):
    pass

class Map(object):

    roomnames = {
        'the wine fields': WineFields(),
    }

    def __init__(self, next_one):
        self.next_one = next_one

    def change(self, next_one):
        return Map.roomnames[next_one]

I have tried some methods to solve this, for example using

def __eq__(self, other):
    return self.next_one == other.next

inside the Map class, but either I placed it wrong or I should not be using it for this problem at all. I got this idea from another StackOverflow page on roughly the same problem:

Learn Python the Hard Way, Ex 49 : Comparing objects using assert_equal

Could someone please explain to me how I can assert that the output I get is what I expect, and not worry about whether the location is the same?


Solution

  • You need to be able to identify each instance:

    class X:
    
        def __init__(self, x):
            self.x = x
    
        def __eq__(self, other):
            return self.x == other.x 
    

    This will mean that constructing them will need a parameter:

    one = X(1)
    other = X(1)
    one == other
    

    The two different instances will equate to each other due to the member x being equal.

    In fact I've just replicated the accepted answer in the question you reference