[英]How to unit test this python class?
我的代码的可测试性有问题。 这与我的类布局和python包布局有关。
我希望此问题的下列结果之一:
基类是AuthenticationToken
。 这两个类HardwareToken
和Keyfile
继承自它。
AuthenticationToken
可以序列化为字符串,反之亦然。 这是我实现反序列化的方式:
class AuthenticationToken(object):
@classmethod
def try_deserialize(cls, spec: str):
for subclass in cls.__subclasses__():
token = subclass.try_deserialize(spec)
if token:
return token
return None
我每个班级只有一个文件,并将它们放在包目录中
package
+-- __init__.py
+-- authentication_token.py
+-- hardware_token.py
+-- keyfile.py
现在,我更喜欢引用诸如package.Keyfile
类的类,而不是package.keyfile.Keyfile
。 在我可以使用try_derialize
方法之前,Python还会看到Authentication令牌的所有子类定义。 这就是为什么我将所有类导入__init__.py
:
from .authentication_token import AuthenticationToken
from .hardware_token import HardwareToken
from .keyfile import Keyfile
现在,我想对AuthenticationToken
类进行单元测试,而不引用其子类。 这个想法是编写一个TestAutheticationToken
类,并在测试期间将其用作单个子类:
import unittest
from package import AuthenticationToken
class TestSubclass(AuthenticationToken):
pass
class TestAuthenticationToken(unittest.TestCase):
# This test fails
def test_bad_case(self):
should_be_none = AuthenticationToken.try_deserialize("Keyfile")
self.assertIsNone(should_be_none)
if __name__ == '__main__':
unittest.main()
该测试失败,因为try_deserialize
创建了一个Keyfile
类型的对象。 这是因为__init__.py
被求值。 如果我直接从模块中导入AuthenticationToken
也是如此:
from package.authentication_token import AuthenticationToken
所以问题是:如何在测试AuthenticationToken
时防止导入Keyfile
和HardwareToken
类?
否则,如何更改类和/或程序包的布局,以便我可以彼此独立地导入所有类,同时仍保留上述好处?
该代码很难测试,因为令牌提供者列表是隐式的 。 这取决于已加载的模块。 我建议您至少给出令牌提供者的明确列表选项 。 要么要求在启动时注册令牌提供者,要么为令牌提供者列表提供可选参数。
这是我能想到的最简单的更改:
class AuthenticationToken(object):
@classmethod
def try_deserialize(cls, spec: str, token_providers=None):
if token_providers is None:
token_providers = cls.__subclasses__()
for subclass in token_providers:
token = subclass.try_deserialize(spec)
if token:
return token
return None
现在您的常规代码保持不变,并且您的测试可以如下所示:
def test_bad_case(self):
should_be_none = AuthenticationToken.try_deserialize(
"Keyfile",
token_providers=[TestSubclass])
self.assertIsNone(should_be_none)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.