Pergunta

Estou encontrando um problema estranho ao usar unittest.assertRaises. Ao executar o código abaixo, recebo a seguinte saída:

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)

A exceção correta é aumentada, mas o teste falha! Se estou pegando o BaseError O teste é bem -sucedido.

De alguma forma MyError Classe de exceção. Alguém pode explicar isso? Existe alguma solução alternativa?

Estou testando o seguinte código Python, que é uma implementação para os objetos de construção dinamicamente por seus nomes de classe.

Este é o módulo base "bases.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)

Este é o módulo a ser testado, "Derived.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()
Foi útil?

Solução

Quando você é derivado.py, é executado como o __main__ Módulo (já que você o executou diretamente em vez de importá -lo). Quando você o importa mais tarde explicitamente, outra cópia do módulo é criada, desta vez sob o nome derived. Então __main__.MyError não é o mesmo que derived.MyError, e a exceção não é pega.

Outras dicas

Como mencionado, a questão é módulos __a Principal__ e derivado não são o mesmo; Esta resposta é sobre como você conserta isso.

Não Misture o código do módulo e o código de script. Comece a pensar em if __name__ == "__main__" código como a Hack. (Ainda é muito conveniente às vezes e eu o uso frequentemente para depuração, etc., mas Visão Como um hack, você sempre recebe um leve empurrão mental escrevendo.) O novo script que executaria tudo seria simples (e nunca importado):

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

Ou com várias diferenças por preferência pessoal. Apenas certifique -se de adicionar derivado.Main para fazer o que quiser.

Eu também vi outro hack que é menos comum, no topo de derivado.py:

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

Enquanto desperdício em analisar o mesmo código duas vezes, isso é independente em troca.

O problema é provavelmente que o seu BaseClass.get() O método está retornando a você outra classe. A propósito, esse método é horrível em si, eu me pergunto por que você está fazendo isso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top