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.
Quick Example: I'd like to test the zoo_str
method, even though it depends on the abstract description
method. 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
).
class Animal:
@abstractmethod
def description(self) -> str:
pass
def zoo_str(self) -> str:
return self.description() "Get more info at zoo.com!"
CodePudding user response:
Just create a subclass.
class TestAnimal(Animal):
def description(self):
return "foo"
assert TestAnimal().zoo_str() == "fooGet more info at zoo.com!"
CodePudding user response:
You can simply use multiple 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!"
CodePudding user response:
Here is a mock-using variant (based on https://stackoverflow.com/a/63777635) showing how to test against all Animal
subclasses:
@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!"