[英]how can i test an abstract method in python 2.6
我有一个抽象类:
import abc
class Hello(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def add(self, foo):
pass
@abc.abstractmethod
def remove(self, foo):
pass
我正在使用abc做抽象方法,所以,当我这样做时:
hello = Hello()
并引发此错误: TypeError: Can't instantiate abstract class Hello with abstract methods add, remove
所以我可以测试这种类型错误:
self.assertRaises(Exception, Hello) # but this only test the constructor and i can't get the 100% of code coverage. I need call the add method and the remove method
额外的问题:任何人都知道如何在python 2.6中断言消息异常? (你不能使用with:
for raise assertions。)
如何测试这种抽象方法以获得100%的代码覆盖率?
如何创建抽象方法的文档字符串而不是使用这里提到的pass
, https://stackoverflow.com/a/19275908/469992 ? 它还可以用于提供有关该方法在子类中应该执行的操作的一些信息。
abstract.py,
from abc import ABCMeta, abstractmethod
class A(object):
__metaclass__ = ABCMeta
@abstractmethod
def some_method(self):
"This method should ..."
class B(A):
def some_method(self):
return 1
test_abstract.py,
import unittest
import abstract
class TestB(unittest.TestCase):
def test(self):
self.assertEqual(abstract.B().some_method(), 1)
然后,使用python 2.6.8, nosetests --with-xcoverage
输出,
.
Name Stmts Miss Cover Missing
----------------------------------------
abstract 7 0 100%
----------------------------------------------------------------------
Ran 1 test in 0.004s
如何检查类dict中的键:
>>> Hello.__dict__.has_key('__abstractmethods__')
True
>>> Hello.__dict__.has_key('__metaclass__')
True
>>>
您可以确保将Hello.__abstractmethods__
定义的所有方法覆盖到子类中。
>>> Hello.__abstractmethods__
frozenset(['add', 'remove'])
>>>
如果您错过了在子类中重新定义任何这些方法,您仍会获得错过方法的TypeError:
TypeError: Can't instantiate abstract class Abs_Hello with abstract methods remove
或者像这样测试:
def check_all(abstract, sub_class):
abs_method = abstract.__abstractmethods__
for m in abs_method:
if not isinstance(m, sub_class):
raise TypeError("%s is not defined in subclass %s" % (m, repr(sub_class)))
你永远不应该实例化一个抽象类。 您看到该错误的原因是设计原因。 抽象方法在它们的子类中实现,因为它定义了类不同的行为。 抽象类封装了这些子类之间共享的行为。
为了说明,你想要这样的东西:
class Language(Hello):
def add(self, foo):
self.baz.append(foo)
def remove(self, foo):
self.baz[foo] = None
注意Language
如何从Hello
继承。 所以你应该测试抽象类的子类的实例,而不是抽象类本身。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.