Я хочу проверить, что деструктор объекта Python вызывается и работает правильно, то есть он не вызывает ошибок и не возвращает неверный код выхода.
Я застрял в написании модульного теста,потому что кажется, что модульное тестирование заканчивается до удаления объекта.Мне не удалось принудительно удалить объект до завершения теста, и я не могу позволить себе вызывать __del__
непосредственно в моих тестах по двум причинам:
Это не совсем такто, что я тестирую
Это фактически приводит к тому, что объект уничтожается дважды, и в моем случае деструктор освобождает часть памяти, поэтому при вызове дважды он создает ошибку сегментации.
Чтобы проиллюстрировать это, я создал игрушечный пример, где у меня есть два объекта.Первый, MyWrongObject
, содержит ошибку в деструкторе, а второй MyCorrectObject
является правильным.Я написал тесты для каждого из этих объектов.Один из них должен быть успешным, а другой - неудачным.
import unittest
import gc
class MyWrongObject(object):
def __init__(self):
self.del_calls = 0
def __del__(self):
if self.del_calls:
# Something really bad can happen here like a segmentation fault
# because we may free some memory twice
raise AssertionError("Already destroyed")
self.del_calls += 1
# Simulate an error
raise ValueError("Error while destroying the object")
class MyCorrectObject(object):
def __init__(self):
self.del_calls = 0
def __del__(self):
if self.del_calls:
# Something really bad can happen here like a segmentation fault
# because we may free some memory twice
raise AssertionError("Already destroyed")
self.del_calls += 1
# No error here
class TestDestructor(unittest.TestCase):
def test_my_correct_object_should_destroy_itself(self):
# Given
my_object = MyCorrectObject()
# When / Then
del my_object
gc.collect()
# This test should fail
def test_my_wrong_object_should_destroy_itself(self):
# Given
my_object = MyWrongObject()
# When / Then
del my_object
gc.collect()
В текущем состоянии оба теста пройдены успешно, а второй выводит ValueError
в стандартный вывод:
python -m unittest snips_nlu.tests.test_destructor.TestDestructor 1 ↵
.Exception ignored in: <bound method MyWrongObject.__del__ of <snips_nlu.tests.test_destructor.MyWrongObject object at 0x1118bbda0>>
Traceback (most recent call last):
File "/Users/adrien/dev/snips-nlu/snips_nlu/tests/test_destructor.py", line 17, in __del__
raise ValueError("Error while destroying the object")
ValueError: Error while destroying the object
.
----------------------------------------------------------------------
Ran 2 tests in 0.044s
OK
Я могуне удается написать эти тесты согласованным образом (используя один и тот же код в обоих) и выполнить первый проход, в то время как второй выходит из строя (без AssertionError
в stdout).
Спасибо заваша помощь!