长话短说,我完全可以模仿类方法,当它只是那个被mock对象替换的方法时,但是当我试图用mock对象替换整个类时,我无法模仿这个方法
@mock.patch.object
成功地模拟了scan
方法,但@mock.patch
未能这样做。我以
https://docs.python.org/3/library/unittest.mock.html#unittest.mock.patch
但显然我做错了什么。在
在这两种情况下,我都在同一个命名空间中模拟lexicon模块(它是由import lexicon
在sentence_parser
中导入的),但是mock_lexicon is lexicon.lexicon
检查失败
#!python
import sys;
sys.path.append('D:\python\lexicon');
import lexicon;
import sentence_parser;
import unittest2 as unittest;
import mock;
class ParserTestCases(unittest.TestCase) :
def setUp(self) :
self.Parser = sentence_parser.Parser();
@mock.patch('lexicon.lexicon')
def test_categorizedWordsAreAssigned_v1(self, mock_lexicon) :
print "mock is lexicon:";
print mock_lexicon is lexicon.lexicon + "\n";
instance = mock_lexicon.return_value;
instance.scan.return_value = "anything";
self.Parser.categorize_words_in_sentence("sentence");
instance.scan.assert_called_once_with("sentence");
@mock.patch.object(lexicon.lexicon, 'scan')
def test_categorizedWordsAreAssigned_v2(self, mock_scan) :
mock_scan.return_value = "anything";
self.Parser.categorize_words_in_sentence("sentence");
mock_scan.assert_called_once_with("sentence");
if (__name__ == '__main__') :
unittest.main()
输出:
^{pr2}$编辑:
为了澄清,Parser
的定义如下
#!python
import sys;
sys.path.append('D:\python\lexicon');
import lexicon;
class Parser(object) :
my_lexicon = lexicon.lexicon()
def __init__(self) :
self.categorized_words = ['test'];
def categorize_words_in_sentence(self, sentence) :
self.categorized_words = self.my_lexicon.scan(sentence);
if (__name__ == '__main__') :
instance = Parser();
instance.categorize_words_in_sentence("bear");
print instance.categorized_words;
这里真正相关的是
categorize_words_in_sentence
Parser
的方法如何使用lexicon
。但首先我们应该消除噪音:是什么能把我们引向错误的方向:试着用
^{pr2}$你会明白你在打印},而是{}。在
False
,因为mock_lexicon
不是{现在我无法告诉您为什么第一个测试不起作用,因为答案在
categorize_words_in_sentence
方法中,或者更可能在sentence_parser
模块中,我可以猜到您可以有类似的在这两种情况下,请参阅Where to Patch文档,这些文档可以启发您了解问题的原因以及您在案例中真正需要修补的地方。在
第二个版本的工作仅仅是因为您正在修补对象而不是引用(这应该是不同的)。在
最后,更简洁和一般的版本可以是:
还有一件事:删除
unittest2
至少你没有使用python2.4,而且你对后端口的unittest特性感兴趣。在[编辑]
现在我可以停下来猜测并指出为什么第一个版本不起作用,也永远不会起作用:
Parser.my_lexicon
属性在加载时间时计算。这意味着当您导入sentence_parser
时,将创建一个lexicon
,并且与{lexicon.lexicon
时,这个引用保持不变,解析器对象仍然使用导入时创建的原始引用。在您可以做的是修补
Parser
类中的引用如果您想给您的mock提供相同的} 。在
lexicon
签名,可以使用^{相关问题 更多 >
编程相关推荐