Function that disposes of every unittest.mock.Mock object in a container and then of the container and how to verify disposal?

44 views Asked by At

I'm working on a library for hextile map related algorithms (basically the stuff described on redblobgames.com), I’m finished with the actual code and now working on the tests. I did plan on writing to „helper functions“ to make the unit tests easier. The first one is a code to quickly generate and modify a container containing objects with hexagonal coordinates and then modify the attributes of the objects to test for errors etc. While the generator function is working fine, the teardown one isn’t, I presume it has something to do with copy, pointers and the likes, but being self taught at this point in time, I’m at a loss.

In short, it does not dispose the objects nor the container as intended. I need help with the "testgrp_teardown(test_grp:list) -> None" function.

import unittest
from unittest.mock import Mock

def testgrp_generator(center_obj:object|tuple|HexCoords, radius:int, override_coords:tuple=False) -> set:
    """
    Generate a set containing objects with q, r and s attributes to simulate a 
    coordinate groups or a SpriteGroup allow unittests on more complex functions.
    Override coordinates must be formatted as follows: 
    (q, r, s, {attribute_name : override_value})
    """
    # obj_grp containing all objects with 2 dist from start ----------------- #
    obj_grp = list()
    # coords of all objects with distance 2 from start_obj ------------------ #
    all_coords = list(in_range(center_obj, radius))
    # add objects to obj_grp ------------------------------------------------ #
    for coords in all_coords:
        # generate generic object ------------------------------------------- #
        obj = Mock()
        obj.q = coords[0]
        obj.r = coords[1]
        obj.s = coords[2]
        obj.block = False
        obj_grp.append(obj)
    # generate list as basis to modify obj_grp ------------------------------ #
    index_to_override = list()
    if override_coords:
        for i in range(len(obj_grp)):
            for o_coords in override_coords:
                if o_coords[0] == obj_grp[i].q and o_coords[1] == obj_grp[i].r and o_coords[2] == obj_grp[i].s :
                    index_to_override.append([i, o_coords[3]])
    # modify generic objects with override ---------------------------------- #             
    for override in index_to_override:
        for key in override[1].keys():
            if override[1][key] != "del":
                setattr(obj_grp[override[0]], key, override[1][key])
            else:
                delattr(obj_grp[override[0]], key)
        
    return obj_grp


def testgrp_teardown(test_grp:list) -> None:
    """
    Clean dispose of the Mock objects in test_grp.
    """
    for obj in test_grp:
        obj.dispose()
    del test_grp

I tried a couple of different variants, the one in the code is for clarity of what I want to do.

Bonus points for adding a small section on how to verify disposal. My approach would be to collect the object names and then check if they are in locals or globals.

0

There are 0 answers