我有一种方法要进行单元测试。该方法需要一个文件路径,然后使用上下文管理器打开该文件路径,以解析一个返回值(如果存在的话),该值应足够简单。
@staticmethod
def read_in_target_language(file_path):
"""
.. note:: Language code attributes/values can occur
on either the first or the second line of bilingual.
"""
with codecs.open(file_path, 'r', encoding='utf-8') as source:
line_1, line_2 = next(source), next(source)
get_line_1 = re.search(
'(target-language=")(.+?)(")', line_1, re.IGNORECASE)
get_line_2 = re.search(
'(target-language=")(.+?)(")', line_2, re.IGNORECASE)
if get_line_1 is not None:
return get_line_1.group(2)
else:
return get_line_2.group(2)
出于明显的原因,我想避免针对外部文件进行测试,并且不希望创建临时文件。另外,在这种情况下,我不能使用StringIO。
如何在单元测试用例中模拟file_path对象?最终,我需要创建一个包含不同值的模拟路径。感谢您的帮助。
答案 0 :(得分:0)
(免责声明:我不会说Python,所以我很可能会在细节上犯错)
我建议您改为嘲笑codecs
。使模拟的open
方法返回一个对象,其中包含要从read
调用中返回的测试数据。这可能涉及为返回值创建另一个模拟对象。我不知道您是否可以在Python中使用某些股票类代替。
然后,为了实际启用测试逻辑,请向read_in_target_language
添加一个参数,该参数表示可以承担原始codecs
对象角色的对象,即,按参数进行依赖项注入。为方便起见,我想您可以将其默认设置为codecs
。
我不确定Python的鸭子类型在静态和实例方法方面能走多远,但是类似这样的东西应该可以使您大致了解:
def read_in_target_language(file_path, opener=codecs):
...
with opener.open(file_path, 'r', encoding='utf-8') as source:
如果上述操作不可行,则可以添加一个间接层:
class CodecsOpener:
...
def open(self, file_path, access, encoding):
return codecs.open(file_path, access, encoding)
class MockOpener:
...
def __init__(self, open_result):
self.open_result = open_result
def open(self, file_path, access, encoding):
return self.open_result
...
def read_in_target_language(file_path, opener=CodecsOpener()):
...
with opener.open(file_path, 'r', encoding='utf-8') as source:
...
...
def test():
readable_data = ...
opener = MockOpener(readable_data)
result = <class>.read_in_target_language('whatever', opener)
<check result>