我的代码可测试性存在问题。这与我的类布局和我的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
方法之前,python还可以看到Authentication标记的所有子类定义。这就是我在try_derialize
中导入所有类的原因:
__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
时阻止导入类Keyfile
和HardwareToken
?
或者我如何更改类和/或包布局,以便我可以相互独立地导入所有类,同时仍保留上述优点?
答案 0 :(得分:0)
代码很难测试,因为令牌提供程序列表是隐式。这取决于已加载的模块。我建议你至少给出明确的令牌提供者列表的选项。要么在启动时注册令牌提供程序,要么为令牌提供程序列表提供可选参数。
这是我能想到的最简单的改变:
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)