Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can i test an abstract method in python 2.6

I have an abstract class:

import abc


class Hello(object):
    __metaclass__ = abc.ABCMeta

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

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

I'm using abc for do abstract methods, so, when i do:

hello = Hello()

and this error is raised: TypeError: Can't instantiate abstract class Hello with abstract methods add, remove

So I can test this type error with:

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

Extra question: anybody knows how can i assert the message exception in python 2.6? (you can't use the with: for raise assertions.)

How can i test this abstract methods for get the 100% of code coverage?

like image 353
fj123x Avatar asked Jan 25 '14 14:01

fj123x


People also ask

How do you test an abstract class?

There are two ways to unit test a class hierarchy and an abstract class: Using a test class per each production class. Using a test class per concrete production class.

How do you access the abstract method in Python?

To define an abstract method we use the @abstractmethod decorator of the abc module. It tells Python that the declared method is abstract and should be overridden in the child classes. We just need to put this decorator over any function we want to make abstract and the abc module takes care of the rest.

How do you write a test case for an abstract class in Python?

There are two options to test an abstract base class (ABC) in Python: you can either override or patch the __abstractmethods__ property to be able to instantiate the abstract class and test it directly or you can create a child class that implements all the abstract methods of the base class.

Can a class have 2 abstract methods in Python?

Note the abstract base class may have more than one abstract methods. The child class must implement all of them failing which TypeError will be raised.


1 Answers

What about creating a doc string of the abstract method instead of using pass as mentioned here, https://stackoverflow.com/a/19275908/469992 ? It can also be used to give some information about what the method is supposed to do in the sub classes.

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)   

Then, using python 2.6.8, nosetests --with-xcoverage outputs,

.
Name       Stmts   Miss  Cover   Missing
----------------------------------------
abstract       7      0   100%   
----------------------------------------------------------------------
Ran 1 test in 0.004s  
like image 66
sveitser Avatar answered Sep 28 '22 15:09

sveitser