2015-05-29 7 views
2

Предположим, что у меня есть функция, которая документирована, чтобы принять collections.Sequence ABC. Как проверить код внутри этой функции на интерфейсе ABC? Могу ли я написать единичный тест (или тесты), подтверждающий, что мой код вызывает только методы, определенные этим ABC, а не, скажем, метод, определяемый list или какой-либо другой конкретной реализацией collections.Sequence? Или есть какой-то другой инструмент или метод для проверки этого?Проверьте, что код Python использует только методы ABC

ответ

1

Просто проверьте функцию, передав экземпляр класса, который реализует только эти методы. Если вам нужно, вы можете унаследовать встроенный тип такого, как list и переопределить его метод __getattribute__, как это:

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) 
+0

«экземпляр класса, который реализует только те методы» - это суть того, что я спрашиваю , Я думаю: есть ли более простой способ получить такую ​​вещь? Ваш метод работает, но дублирует информацию, которая уже находится в ABC. Таким образом, существует риск выхода из синхронизации, принятия другой ошибки и т. Д. (Кроме того, если кто-то должен был это сделать, им может быть лучше использовать макет или аналогичные ... в зависимости от теста.) – detly

+0

Будет использовать 'если имя не в Sequence .__ abstractmethods__' решает вашу проблему? – jangler

+0

Я обновлю свой ответ, чтобы отразить это. – jangler

0

Реализовать ABC непосредственно сам, с помощью методов, как тривиальные или сложный по мере необходимости кода:

import collections 

class TestSequence(collections.Sequence): 

    def __init__(self): 
     pass 

    def __len__(self): 
     return 3 

    def __getitem__(self, index): 
     return index 

Если вы допустили ошибку и пропустить абстрактные реализации метода, ваш код будет выдавать ошибку:

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

Если ваш код тестируемого вызывает метод не определен ABC, вы увидите обычный никакой ошибки атрибута:

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