Предположим, что у меня есть функция, которая документирована, чтобы принять collections.Sequence
ABC. Как проверить код внутри этой функции на интерфейсе ABC? Могу ли я написать единичный тест (или тесты), подтверждающий, что мой код вызывает только методы, определенные этим ABC, а не, скажем, метод, определяемый list
или какой-либо другой конкретной реализацией collections.Sequence
? Или есть какой-то другой инструмент или метод для проверки этого?Проверьте, что код Python использует только методы ABC
2
A
ответ
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 непосредственно сам, с помощью методов, как тривиальные или сложный по мере необходимости кода:
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'
«экземпляр класса, который реализует только те методы» - это суть того, что я спрашиваю , Я думаю: есть ли более простой способ получить такую вещь? Ваш метод работает, но дублирует информацию, которая уже находится в ABC. Таким образом, существует риск выхода из синхронизации, принятия другой ошибки и т. Д. (Кроме того, если кто-то должен был это сделать, им может быть лучше использовать макет или аналогичные ... в зависимости от теста.) – detly
Будет использовать 'если имя не в Sequence .__ abstractmethods__' решает вашу проблему? – jangler
Я обновлю свой ответ, чтобы отразить это. – jangler