assertRaises просто перехватывает базовое исключение - PullRequest
0 голосов
/ 06 января 2010

У меня странная проблема при использовании unittest.assertRaises. При выполнении кода ниже я получаю следующий вывод:

E
======================================================================
ERROR: testAssertRaises (__main__.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\home\python_test\src\derived.py", line 29, in testAssertRaises
    self.assertRaises(MyError, self.raiser.raiseMyError)
  File "C:\Programme\Python26\lib\unittest.py", line 336, in failUnlessRaises
    callableObj(*args, **kwargs)
  File "C:\home\python_test\src\derived.py", line 15, in raiseMyError
    raise MyError("My message")
MyError: 'My message'

----------------------------------------------------------------------
Ran 1 test in 0.000s

FAILED (errors=1)

Возникает правильное исключение, но тест не пройден! Если я поймаю BaseError, тест пройден успешно.

Почему-то проблема в том, что unittest не может видеть класс исключений MyError. Кто-нибудь может это объяснить? Есть ли обходной путь?

Я тестирую следующий код Python, который является реализацией для динамического конструирования объектов по именам классов.

Это базовый модуль "base.py":

class BaseClass(object):

    @staticmethod
    def get(className):
        module = __import__("derived", globals(), locals(), [className])
        theClass = getattr(module, className)
        return theClass()


class BaseError(Exception):

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

    def __str__(self):
        return repr(self.msg)

Это модуль для проверки, "output.py":

import unittest

from bases import BaseError
from bases import BaseClass


class MyErrorRaiser(BaseClass):    

    def raiseMyError(self):
        raise MyError("My message")


class MyError(BaseError):
    '''
    '''


class Test(unittest.TestCase):

    def setUp(self):
        self.raiser = BaseClass.get("MyErrorRaiser")

    def testAssertRaises(self):
        self.assertRaises(MyError, self.raiser.raiseMyError)


if __name__ == "__main__":
    unittest.main()

Ответы [ 3 ]

2 голосов
/ 06 января 2010

Как упомянуто , проблема заключается в том, что модули __ main __ и производные не являются одним и тем же; этот ответ о том, как вы это исправите.

Не смешивайте код модуля и код скрипта. Начните думать о if __name__ == "__main__" коде как о хаке . (Иногда это все еще очень удобно, и я часто использую его для отладки и т. Д., Но рассматривает как хак, так что вы всегда получаете легкое умственное толчок при написании.) Новый сценарий, который затем запускает все будет простым (и никогда не импортированным):

#!/usr/bin/env python
import derived
import sys
sys.exit(derived.main(sys.argv[1:]))

Или с различными различиями по личным предпочтениям. Просто убедитесь, что вы добавили производные.основной, чтобы делать то, что вы хотите.

Я также видел еще один менее распространенный хак в top производного. Py:

import sys
if __name__ == "__main__":
  import derived # import the same module under its "correct" name
  sys.exit(derived.main(sys.argv[1:]))

Несмотря на расточительность парсинга одного и того же кода дважды, в обмене он самодостаточен.

1 голос
/ 06 января 2010

Когда вы запускаете производный.py, он запускается как модуль __main__ (поскольку вы запустили его напрямую, а не импортировали). Когда вы позже импортируете его явно, создается другая копия модуля, на этот раз под именем derived. Так что __main__.MyError - это не то же самое, что derived.MyError, и исключение не перехватывается.

0 голосов
/ 06 января 2010

Возможно, проблема в том, что ваш метод BaseClass.get() возвращает вам другой класс. Кстати, этот метод сам по себе ужасен, мне интересно, почему вы это делаете.

...