#python #unit-testing #python-unittest
Вопрос:
У меня есть класс, как:
"""A"""
from clay import config
from datetime import timedelta
from <path> import B
EXECUTION_TIMEOUT = timedelta(minutes=30)
class A(B):
"""Crawler task for A"""
def __init__(self, *args, **kwargs):
"""Initialization."""
super(A, self).__init__(execution_timeout=EXECUTION_TIMEOUT, *args, **kwargs)
У меня есть тестовый файл в виде :
"""Test class for A"""
from datetime import timedelta, datetime
from doubles import allow
from mock import patch, MagicMock
from unittest import TestCase
import mock
from <path> import A
class JobInfoHandler:
"""Mock job info."""
def __init__(self):
"""Init Method."""
self.crawlerConfig = None
pass
class TestA(TestCase):
"""Test class for A."""
def setUp(self):
"""Create instance of class to test."""
job_info_ob = JobInfoHandler()
self.obj_a = A(owner='arahej', task_id='12',
schedule_interval=timedelta(minutes=60), job_info=job_info_ob)
Когда я запускаю свою команду тестового покрытия. Приведенная ниже строка не покрыта :
super(A, self).__init__(execution_timeout=EXECUTION_TIMEOUT, *args, **kwargs)
Может ли кто-нибудь помочь мне с тем, как освещать super
здесь. Я пытался издеваться или исправлять, но это не сработало.
Комментарии:
1. Это следствие
A
того, что класс не создается, что происходит из-за того, что не определены тесты, которые на самом деле требуют создания экземпляраA
(на самом деле, вообще никаких тестов).
Ответ №1:
setUp()
Метод вызывается только тогда, когда вы пишете метод тестирования, как описано в документации:
setUp()
Метод, вызванный для подготовки испытательного приспособления. Это вызывается непосредственно перед вызовом метода тестирования;…
class TestA(TestCase):
"""Test class for A."""
def setUp(self):
"""Create instance of class to test."""
print("Setting up testcase")
job_info_ob = JobInfoHandler()
self.obj_a = A(owner='arahej', task_id='12',
schedule_interval=timedelta(minutes=60), job_info=job_info_ob)
Здесь вы не определили никакого метода тестирования, поэтому setUp()
он никогда не будет вызван, поэтому A
он никогда не будет инициализирован, что, в свою очередь, никогда не вызовет инициализацию родительского B
элемента via super().__init__()
.
$ coverage run -m unittest discover
----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK
$ coverage html
Теперь будет запущен метод добавления теста setUp()
A.__init__()
, который инициализирует, что, в свою очередь, выполняется B.__init__()
через super()
.
class TestA(TestCase):
def setUp(self):
...
def test_first(self):
print("1st test method called")
assert True
$ coverage run -m unittest discover
Setting up testcase
1st test method called
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
$ coverage html
Кроме того, вы упомянули о насмешках/исправлениях. Вы, может быть, непонимание того, что издевается над/патчи, потому что если вы дразните/патч вызов super().__init__()
с заглушкой реализации, то она бы не назвал фактическую реализацию и вместо того, чтобы вызвать глумились/латать/уменьшенные версии, что означает, что оно не решит вашу проблему, потому что охват вашей фактической реализации не будет хватать, как вы заменили фактический звонок с пропатчен один. Другими словами, вы просто усугубляете свою проблему, исправляя 🙂
Комментарии:
1. @Нил. Лучшее объяснение. Большое Вам спасибо
Ответ №2:
Попробуйте исправить супер:
from mock import patch
class B(object):
def foo(self):
print('foo from B')
class A(B):
def foo(self):
self.called_foo = True
super(A, self).foo()
class TestA(object):
@patch('%s.super' % __name__, create=True)
def test_foo(self, super_func):
A = A()
A.foo()
assert A.called_foo
assert super_func.called