detly
detly

Reputation: 30342

Test that Python code only uses ABC methods

Let's say I have a function that is documented to take a collections.Sequence ABC. How do I test the code within this function against the ABC interface? Can I write a unit test (or tests) confirming that my code only calls methods defined by this ABC and not, say, a method defined by list or some other concrete implementation of collections.Sequence? Or is there some other tool or method to verify this?

Upvotes: 2

Views: 180

Answers (2)

jangler
jangler

Reputation: 987

Simply test the function by passing an instance of a class that only implements those methods. If you need to, you can subclass a built-in type such as list and override its __getattribute__ method, like this:

class TestSequence(list):
    def __getattribute__(self, name):
        if name not in collections.Sequence.__abstractmethods__:
            assert(False) # or however you'd like the test to fail
        return object.__getattribute__(self, name)

Upvotes: 1

detly
detly

Reputation: 30342

Implement the ABC directly yourself, with methods as trivial or complex as needed by the code:

import collections

class TestSequence(collections.Sequence):

    def __init__(self):
        pass

    def __len__(self):
        return 3

    def __getitem__(self, index):
        return index

If you make a mistake and omit abstract method implementations, your code will produce an error:

TypeError: Can't instantiate abstract class TestSequence with abstract methods __getitem__

If your code under test calls a method not defined by the ABC, you will see the usual no attribute error:

AttributeError: 'TestSequence' object has no attribute 'pop'

Upvotes: 0

Related Questions