如何在python2.6中测试抽象方法

2024-09-29 00:21:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一门抽象课:

import abc


class Hello(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def add(self, foo):
        pass

    @abc.abstractmethod
    def remove(self, foo):
        pass

我使用abc进行抽象方法,因此,当我使用时:

^{pr2}$

并引发此错误: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

额外的问题:有人知道在Python2.6中如何断言消息异常?(不能将with:用于引发断言。)

如何测试这些抽象方法以获得100%的代码覆盖率?在


Tags: the方法selfabstractaddhellofoodef
3条回答

创建一个抽象方法的doc字符串,而不是使用这里提到的passhttps://stackoverflow.com/a/19275908/469992,怎么样?它还可以用来提供一些关于方法在子类中应该做什么的信息。在

在摘要.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

试验_摘要.py你说

^{pr2}$

然后,使用python2.6.8,nosetests with-xcoverage输出

.
Name       Stmts   Miss  Cover   Missing
                    
abstract       7      0   100%   
                                   
Ran 1 test in 0.004s  

你不应该实例化一个抽象类。你看到错误的原因是故意的。抽象方法在它们的子类中实现,因为这定义了类不同的行为。抽象类封装了这些子类之间共享的行为。在

为了说明这一点,你需要这样的东西:

class Language(Hello):

    def add(self, foo):
        self.baz.append(foo)

    def remove(self, foo):
        self.baz[foo] = None

注意Language是如何从^{继承的。 所以实际上你应该测试抽象类的一个子类的实例,而不是抽象类本身。在

那在课堂上检查一下钥匙吧

>>> Hello.__dict__.has_key('__abstractmethods__')
True
>>> Hello.__dict__.has_key('__metaclass__')
True
>>>

您可以确保将Hello.__abstractmethods__中定义的所有方法覆盖到子类中。在

^{pr2}$

如果您未能在子类中重新定义这些方法中的任何一个,则仍将获得缺少的方法的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)))

相关问题 更多 >