Python 似乎调用了 patch mock,但断言失败
Python patch mock appears to be called, but assert fails
我正在使用 Python 2.6.6
我想做的是用 Mock 替换对象的创建,以确保进行正确的调用。应该是直截了当的。
我的模块:
import dir.SubModule
class Cls( object ):
def Start( self ):
self.__obj = dir.SubModule.SubCls()
self.__obj.foo()
我的测试:
import MyModule
import unittest
from mock import Mock, MagicMock, patch
class MyTest( unittest.TestCase ):
def setUp( self ):
self.uut = MyModule.Cls()
def test_one( self ):
with patch( 'dir.SubModule.SubCls', spec=True ) as mockObj:
print "mock calls before"
print mockObj.mock_calls
self.uut.Start()
print "called: " + str( mockObj.called )
print "foo called: " + str( mockObj.foo.called )
print "call_count: " + str( mockObj.call_count )
print "call_args: " + str( mockObj.call_args )
print "args_list: " + str( mockObj.call_args_list )
print "mock calls:\n" + str( mockObj.mock_calls )
print "method calls:\n " + str( mockObj.method_calls )
输出为:
mock calls before:
[]
called: True
foo called: False
call_count: 1
call_args: call()
args_list: [call()]
mock calls:
[call(), call().foo()]
method calls:
[]
但测试失败:
AssertionError: Expected call: foo()
Not called
我不明白 mock 是如何报告调用的,但我不能断言它们被调用了。我错过了什么?
编辑:
添加所有指标的报告后,似乎我对 python 模拟有一些基本的误解。如果 foo() 在调用列表中,那么为什么调用计数只有 1,为什么 foo.called 报告 'False'?
mockObj.foo
从未在此测试中调用。 self.uut.Start()
调用 mockObj
,创建一个新的 mock,然后调用 那个 mock 的 foo
方法。如果你想断言这个调用发生了,你将需要访问正确的对象:
mockObj.return_value.foo.assert_called_with()
这是 link:
link
我的简单修复:
with patch( 'class' ) as mockCreator:
mockObj = mockCreator.return_value
那我可以随便用'mockObj'了。
我 运行 上周在我第一次学习模拟时 link 编辑了解决方案 - 信息完全吸收还为时过早。
模拟断言语法有很多怪癖。为了处理它,我写了一个 helper library 到
为我生成断言。
以下是您将如何将其用于您的测试方法:
import MyModule
import unittest
from mock import patch
class MyTest( unittest.TestCase ):
def setUp( self ):
self.uut = MyModule.Cls()
def test_one( self ):
with patch( 'dir.SubModule.SubCls', spec=True ) as mockObj:
self.uut.Start()
# calls to generate_asserts, put this after the 'act'
import mock_autogen.generator
print(mock_autogen.generator.generate_asserts(mockObj))
你得到的输出是:
assert 1 == mockObj.call_count
mockObj.assert_called_once_with()
mockObj.return_value.foo.assert_called_once_with()
这与 __init__
调用相关,然后是对新创建对象的 foo
的调用。
所以不再需要自己弄清楚确切的语法,只需应用工具:)
我正在使用 Python 2.6.6
我想做的是用 Mock 替换对象的创建,以确保进行正确的调用。应该是直截了当的。
我的模块:
import dir.SubModule
class Cls( object ):
def Start( self ):
self.__obj = dir.SubModule.SubCls()
self.__obj.foo()
我的测试:
import MyModule
import unittest
from mock import Mock, MagicMock, patch
class MyTest( unittest.TestCase ):
def setUp( self ):
self.uut = MyModule.Cls()
def test_one( self ):
with patch( 'dir.SubModule.SubCls', spec=True ) as mockObj:
print "mock calls before"
print mockObj.mock_calls
self.uut.Start()
print "called: " + str( mockObj.called )
print "foo called: " + str( mockObj.foo.called )
print "call_count: " + str( mockObj.call_count )
print "call_args: " + str( mockObj.call_args )
print "args_list: " + str( mockObj.call_args_list )
print "mock calls:\n" + str( mockObj.mock_calls )
print "method calls:\n " + str( mockObj.method_calls )
输出为:
mock calls before:
[]
called: True
foo called: False
call_count: 1
call_args: call()
args_list: [call()]
mock calls:
[call(), call().foo()]
method calls:
[]
但测试失败:
AssertionError: Expected call: foo()
Not called
我不明白 mock 是如何报告调用的,但我不能断言它们被调用了。我错过了什么?
编辑: 添加所有指标的报告后,似乎我对 python 模拟有一些基本的误解。如果 foo() 在调用列表中,那么为什么调用计数只有 1,为什么 foo.called 报告 'False'?
mockObj.foo
从未在此测试中调用。 self.uut.Start()
调用 mockObj
,创建一个新的 mock,然后调用 那个 mock 的 foo
方法。如果你想断言这个调用发生了,你将需要访问正确的对象:
mockObj.return_value.foo.assert_called_with()
这是 link: link
我的简单修复:
with patch( 'class' ) as mockCreator:
mockObj = mockCreator.return_value
那我可以随便用'mockObj'了。
我 运行 上周在我第一次学习模拟时 link 编辑了解决方案 - 信息完全吸收还为时过早。
模拟断言语法有很多怪癖。为了处理它,我写了一个 helper library 到 为我生成断言。
以下是您将如何将其用于您的测试方法:
import MyModule
import unittest
from mock import patch
class MyTest( unittest.TestCase ):
def setUp( self ):
self.uut = MyModule.Cls()
def test_one( self ):
with patch( 'dir.SubModule.SubCls', spec=True ) as mockObj:
self.uut.Start()
# calls to generate_asserts, put this after the 'act'
import mock_autogen.generator
print(mock_autogen.generator.generate_asserts(mockObj))
你得到的输出是:
assert 1 == mockObj.call_count
mockObj.assert_called_once_with()
mockObj.return_value.foo.assert_called_once_with()
这与 __init__
调用相关,然后是对新创建对象的 foo
的调用。
所以不再需要自己弄清楚确切的语法,只需应用工具:)