Python模拟返回无效值



我有以下结构:

sources/
- parser/
- sources_parser.py # SourcesParser class is here
- tests/
- test_sources_parsers.py # SourcesParserTest is here

sources_parser.py:

from sources.parser.sitemap_parser import SitemapParser
class SourcesParser(object):
__sitemap_parser: SitemapParser
def __init__(self) -> None:
super().__init__()
self.__sitemap_parser = SitemapParser()
def parse(self):
# ... 
urls = self.__parse(source)
self.logger.info(f'Got {len(urls)} URLs')
def __parse(self, source: NewsSource) -> List[str]:
results = self.__sitemap_parser.parse_sitemap(source.url)
self.logger.info(f'Results: {results}, is list: {isinstance(results, list)}')
return results

测试:

class SourcesParserTest(TestCase):
@patch('sources.parser.sources_parser.SitemapParser')
def test_normal_parse(self, mock_sitemap_parser):
mock_sitemap_parser.parse_sitemap.return_value = [
'https://localhost/news/1',
'https://localhost/news/2',
'https://localhost/news/3',
]
parser = SourcesParser()
parser.parse()

日志如下:

Results: <MagicMock name='SitemapParser().parse_sitemap()' id='5105954240'>, is list: False
Got 0 URLs

如果我正确理解了mock,parse_sitemap调用应该返回给定的url列表,但它返回的是一个被转换为空列表的Mock对象。

Python版本为3.9.

怎么了?

如果模拟成员函数,则必须在被模拟的实例对象上模拟函数,而不是在被模拟的类对象上模拟函数。这可能不是完全直观的,因为成员函数属于类,但您可以将其视为绑定与未绑定方法-您必须模拟绑定方法。

对于Mock,模拟实例是通过在类对象上使用return_value来完成的,类似于模拟函数调用的结果,所以在您的情况下您需要:

@patch('sources.parser.sources_parser.SitemapParser')
def test_normal_parse(self, mock_sitemap_parser):
mocked_parser = mock_sitemap_parser.return_value  # mocked instance
mock_parser.parse_sitemap.return_value = [
'https://localhost/news/1',
'https://localhost/news/2',
'https://localhost/news/3',
]
...

(分割模拟仅用于说明)

相关内容

  • 没有找到相关文章

最新更新