如何修补和验证 Class 是否使用特定参数实例化?

How to patch and verify if a Class was instantiated with a specific parameter?

简而言之,这就是我要测试的class。查看 Tokenizer('english') 是否使用 'english'.

创建
def summarize(news):
        language = 'english'
        parser = PlaintextParser.from_string(news.body, Tokenizer(language))

这是测试

    @mock.patch.object(PlaintextParser, 'from_string')
    @mock.patch('sumy.nlp.tokenizers.Tokenizer')
    def test_summarize_tokenizer_is_called_with_english(self, token_mock, parser_mock):
        news_mock = mock.MagicMock()
        body = u"xx"
        type(news_mock).body = mock.PropertyMock(return_value=body)
        Summarizer.summarize(news_mock)
        token_mock.assert_called_with('english')

我不断得到:

AssertionError: Expected call: Tokenizer('english')
Not called

但这应该会过去。请问我错过了什么?

这是模拟的棘手部分。请注意,您正在 sumy.nlp.tokenizers 命名空间中修补 Tokenizer。但是,大概您有一个导入语句,例如:

from sumy.nlp.tokenizers import Tokenizer

在带有 Summarizer 的模块中。这也将 Tokenizer 放入该模块的命名空间中。在其他 (sumy.nlp.tokenizers) 命名空间中打补丁不会影响此处的 Tokenizer


此问题的一个解决方案是将模块中的导入语句更改为 Summarizer:

from sumy.nlp import tokenizers

那么你的函数就变成了:

def summarize(news):
    language = 'english'
    parser = PlaintextParser.from_string(news.body, tokenizers.Tokenizer(language))

另一个 可以 工作的解决方案是简单地在 Summarizer 的命名空间中修补 Tokenizer (尽管这里有更多的微妙之处......)