2009-10-18 2 views
1

У меня есть класс, как следующее:Единичное тестирование метода, вызываемого во время инициализации?

class Positive(object): 
    def __init__(self, item): 
     self._validate_item(item) 
     self.item = item 

    def _validate_item(self, item): 
     if item <= 0: 
      raise ValueError("item should be positive.") 

Я хотел бы написать модульный тест для _validate_item(), как следующее:

class PositiveTests(unittest.TestCase): 
    def test_validate_item_error(self): 
     self.assertRaises(
      ValueError, 
      Positive._validate_item, 
      0 
     ) 

К сожалению, это не будет работать, так как блок тест только передает 0 методу вместо экземпляра класса (для параметра self) и 0. Есть ли какое-либо решение для этого, кроме того, что нужно косвенно проверять этот метод проверки через класс __init__()?

ответ

7

Если вы не используете себя в теле метода, это намек, что она может не обязательно быть членом класса. Вы можете либо переместить функцию _validate_item в область видимости модуля:

def _validate_item(item): 
    if item <= 0: 
     raise ValueError("item should be positive.") 

Или, если он действительно должен оставаться в классе, знак метод статического:

class Positive(object): 
    def __init__(self, item): 
     self._validate_item(item) 
     self.item = item 

    @staticmethod 
    def _validate_item(item): 
     if item <= 0: 
      raise ValueError("item should be positive.") 

Ваше испытание должно работать, как написано.

+0

Мне нравится этот ответ. Если вам кажется, что нужно самостоятельно писать тесты для _validate_item(), скорее всего, это действительно само по себе. –

+0

staticmethods в Python в большинстве случаев бессмысленны, в этом случае используйте classmethod! – u0b34a0f6ae

+0

Я бы не использовал декоратор '@ classmethod' здесь по той же причине, что я бы не определил его как метод экземпляра. Там не используется 'cls'. Учитывая мои druthers, я сделал бы его частной функцией в области модуля. –

1

Вы не создаете экземпляр Positive. Как насчет

Positive()._validate_item, 0 
+0

Этот код вызывает TypeError, потому что 'Positive .__ init __()' отсутствует аргумент 'item'. –

+0

Это показывает, что вы пытаетесь протестировать реализацию «_validate_item», а не интерфейс. Я думаю, что тестирование 'Positive (0)' намного больше, чем тестирование '_validate_item (0)'. – u0b34a0f6ae

+0

Выше комментарий к @gotgenes – u0b34a0f6ae

1

Ну, _validate_item() проверяется через конструктор. Вызов с нулевым или отрицательным значением вызовет исключение ValueError.

Сделав шаг назад, это цель нет? «Требование» заключается в том, что объект не создается с нулевым или отрицательным значением.

Теперь это надуманный пример, поэтому приведенное выше не может быть применимо к реальному классу; Другая возможность, действительно иметь тест, посвященный методу _validate_item(), может заключаться в создании объекта с положительным значением, а затем для вызова validate_item() на нем.

Смежные вопросы