Python:测试摘要 class 和具体的实现细节
Python: Testing abstract class with concrete implementation details
我有一个 class 包含 @abstractmethod
和正常实施方法的混合,我想知道我应该如何测试正常实施。
快速示例:我想测试 zoo_str
方法,即使它依赖于抽象的 description
方法。如果我有 100 只动物,在 Lion class、Antelope class、Hippo class 等中编写测试似乎有点过分了。最好的方法是什么——我的直觉告诉我应该尝试模拟 description
,但我无法实例化 class,如果抽象方法是私有的(_description
),这就会崩溃。
class Animal:
@abstractmethod
def description(self) -> str:
pass
def zoo_str(self) -> str:
return self.description() + "Get more info at zoo.com!"
只需创建一个子类。
class TestAnimal(Animal):
def description(self):
return "foo"
assert TestAnimal().zoo_str() == "fooGet more info at zoo.com!"
你可以简单地使用多重继承:
# test_animals.py
import unittest
from animals import Animal
class TestAnimal(unittest.TestCase, Animal):
def description(self) -> str:
return "Unittest"
def test_zoo_str(self) -> None:
assert self.zoo_str() == "UnittestGet more info at zoo.com!"
这是一个 mock-using 变体(基于 )显示如何针对所有 Animal
子类进行测试:
@pytest.mark.parametrize("cls", Animal.__subclasses__())
def test_animals(mocker, cls):
mocker.patch.multiple(cls, __abstractmethods__=set())
inst = cls()
assert inst.zoo_str() == f"{inst.description()}Get more info at zoo.com!"
我有一个 class 包含 @abstractmethod
和正常实施方法的混合,我想知道我应该如何测试正常实施。
快速示例:我想测试 zoo_str
方法,即使它依赖于抽象的 description
方法。如果我有 100 只动物,在 Lion class、Antelope class、Hippo class 等中编写测试似乎有点过分了。最好的方法是什么——我的直觉告诉我应该尝试模拟 description
,但我无法实例化 class,如果抽象方法是私有的(_description
),这就会崩溃。
class Animal:
@abstractmethod
def description(self) -> str:
pass
def zoo_str(self) -> str:
return self.description() + "Get more info at zoo.com!"
只需创建一个子类。
class TestAnimal(Animal):
def description(self):
return "foo"
assert TestAnimal().zoo_str() == "fooGet more info at zoo.com!"
你可以简单地使用多重继承:
# test_animals.py
import unittest
from animals import Animal
class TestAnimal(unittest.TestCase, Animal):
def description(self) -> str:
return "Unittest"
def test_zoo_str(self) -> None:
assert self.zoo_str() == "UnittestGet more info at zoo.com!"
这是一个 mock-using 变体(基于 Animal
子类进行测试:
@pytest.mark.parametrize("cls", Animal.__subclasses__())
def test_animals(mocker, cls):
mocker.patch.multiple(cls, __abstractmethods__=set())
inst = cls()
assert inst.zoo_str() == f"{inst.description()}Get more info at zoo.com!"