简体   繁体   English

Python:带有具体实现细节的测试摘要 class

[英]Python: Testing abstract class with concrete implementation details

I have a class containing a mixture of @abstractmethod s and normal implementation methods, and I'm wondering how I should go about testing the normal implementations.我有一个 class 包含@abstractmethod和正常实现方法的混合,我想知道我应该如何 go 测试正常实现。

Quick Example: I'd like to test the zoo_str method, even though it depends on the abstract description method.快速示例:我想测试zoo_str方法,即使它依赖于抽象description方法。 If I have 100 animals, it seems like overkill to write a test in the Lion class, the Antelope class, the Hippo class, etc. What's the best way to do this -- my intuition says I should try to mock description , but I can't instatntiate the class and this falls apart if the abstract method is private ( _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!"

Just create a subclass.只需创建一个子类。

class TestAnimal(Animal):
    def description(self):
        return "foo"


assert TestAnimal().zoo_str() == "fooGet more info at zoo.com!"

You can simply use multiple inheritance:您可以简单地使用多个 inheritance:

# 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!"

Here is a mock-using variant (based on https://stackoverflow.com/a/63777635 ) showing how to test against all Animal subclasses:这是一个模拟使用变体(基于https://stackoverflow.com/a/63777635 )展示了如何针对所有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!"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM