- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我的理解是,此处使用的最简单形式的 autospec
将根据提供的参数检查被模拟的函数的签名。其目的是在它们不匹配时引发错误。在下面的代码中,它似乎注入(inject)了一个额外的参数——对象本身。为什么使用 mock 模块的 autospec
会导致此处显示的意外行为?对于这个问题,我在模块 simplebutton
中创建了一个简化版本。当它作为主模块运行时,会打印“这不是开玩笑”这一行。
#module simplebutton
import sys
class _Dialog2:
def callback(self):
print("It's no joke")
def main():
dialog = _Dialog2()
dialog.callback()
if __name__ == '__main__':
sys.exit(main())
测试模块 test_simplebutton
包含两个都有效的测试。两者都模拟了 callback
函数。然而,第二个测试包括 autospec=True
。
@unittest.mock.patch('simplebutton._Dialog2.callback',
name='callback', autospec=True)
在此测试中,本应不带参数调用的回调函数必须使用 dialog
参数调用,否则测试将失败。
编辑: 每个人都知道您不是通过method(instance)
调用方法,而是通过instance .方法()
。那是我的错误。这里需要是 instance1.method('instance2')
,其中 instance1
是模拟,instance2
是包含模拟方法的对象。为此感谢 Michele d'Amico。
mock_callback.assert_called_once_with(dialog)
测试套件如下:
#module test_simplebutton
import unittest
import unittest.mock
import simplebutton
class Test_Dialog(unittest.TestCase):
@unittest.mock.patch('simplebutton._Dialog2.callback',
name='callback')
def test_direct_call_to_callback_by_mocking_1(self, mock_callback):
dialog = simplebutton._Dialog2()
dialog.callback()
mock_callback.assert_called_once_with()
@unittest.mock.patch('simplebutton._Dialog2.callback',
name='callback', autospec=True)
def test_direct_call_to_callback_by_mocking_2(self, mock_callback):
dialog = simplebutton._Dialog2()
dialog.callback()
mock_callback.assert_called_once_with(dialog)
最佳答案
通过 autospec=True
补丁,用具有相同原始对象签名的模拟替换对象(在您的情况下是方法)。此外,无法扩展生成的模拟:尝试访问不在原始定义中(或在 MagicMock()
中)的属性或方法将引发异常。
在第一种情况下(没有 autospec=True
),您正在用一个无界方法修补一个绑定(bind)方法。当您调用修补方法时,mock_callback
将作为函数调用,而不是作为 dialog
对象的绑定(bind)方法调用。
当你在 @patch
装饰器中使用 autospec=True
时,它会用新的绑定(bind)方法 mock_callback
替换原来的方法:这就像所有其他绑定(bind)方法,并将作为第一个参数由自身调用。为了让示例更清楚,我更改了它以更好地解释 autospec=True
补丁参数的行为。
import unittest
import unittest.mock
import simplebutton
class Test_Dialog(unittest.TestCase):
@unittest.mock.patch('simplebutton._Dialog2.callback')
def test_direct_call_to_callback_by_mocking_1(self, mock_callback):
dialog = simplebutton._Dialog2()
dialog.callback()
mock_callback.assert_called_once_with()
mock_callback.reset_mock()
simplebutton._Dialog2.callback()
mock_callback.assert_called_once_with()
@unittest.mock.patch('simplebutton._Dialog2.callback', autospec=True)
def test_direct_call_to_callback_by_mocking_2(self, mock_callback):
dialog = simplebutton._Dialog2()
dialog.callback()
mock_callback.assert_called_once_with(dialog)
self.assertRaises(Exception, simplebutton._Dialog2.callback)
dialog2 = simplebutton._Dialog2()
dialog.callback()
dialog2.callback()
mock_callback.assert_has_calls([unittest.mock.call(dialog), unittest.mock.call(dialog2)])
在第一个测试中,我们通过 simplebutton._Dialog2.callback()
显式调用 _Dialog2.callback()
作为未绑定(bind)的方法,行为正是与 dialog.callback()
相同。
在第二个测试中,如果我们尝试像第一个测试一样将其称为未绑定(bind),它将引发异常。此外,如果我们从两个不同的对象调用该方法,我们将发现对同一个 mock 的两个不同调用,我们可以识别它们。
我希望现在您已经清楚在使用 autospec=True
参数时会发生什么以及您应该期待什么。
关于python - Mock 的 autospec 将错误的参数注入(inject)到被调用的函数中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27878750/
/usr/local/bin/ruby -rrubygems -e "require 'redgreen'" /usr/local/lib/ruby/gems/1.8/gems/rspec-1.3.
我想断言 Python 类中的一个类方法使用一组特定的参数调用另一个类方法。我希望模拟的类方法是“规范的”,因此它会检测是否使用错误数量的参数调用它。 当我使用 patch.object(.., au
我有一个类,它使用@property 装饰器定义了一些属性。当我修补该类并设置 autospec=True 时,我希望该属性的行为符合规范 class MyClass(object): def
在使用 mock.patch 及其变体时,我什么时候应该使用 autospec=True? 一方面,this article警告我们始终使用 autospec=True: ... you should
我想知道这是否在 StackOverflow 上有它的位置,但由于它与编程相关,我会把它扔掉。 这是我的问题。我是 TDD 的新手,我喜欢 Ruby,所以我走的明显路径是用 rspec 测试东西。为什
图书馆模块: # mod.py def foo(): bar1("arg1") bar2("arg2x", "arg2y") def bar1(x): pass def bar
我已经使用 prefix 在 Mac OS X Leopard 上安装了 Ruby 1.9.1 和 Ruby 1.8.6。和 program-suffix选项,以便我可以通过发出 ruby19、i
假设我有一个像下面这样的简单装饰方法: def my_decorator(fn): def _wrapper(*args, **kwargs): print 'Calling decora
我想在文件更改时自动启动构建。 我在 Ruby 中使用过 autospec (RSpec) 并且喜欢它。 如何在 bash 中做到这一点? 最佳答案 看看incron和 inotify-tools .
安装 rspec/ZenTest 并运行 autospec 后,它按预期第一次运行了我的规范。在对我的一个规范进行更改并在第二次运行时,我得到以下结果: /usr/bin/ruby1.8 /usr/l
我的理解是,此处使用的最简单形式的 autospec 将根据提供的参数检查被模拟的函数的签名。其目的是在它们不匹配时引发错误。在下面的代码中,它似乎注入(inject)了一个额外的参数——对象本身。为
我想模拟一个具有以下要求的类: 该类具有公共(public)读/写属性,在其 __init__() 方法中定义 该类具有在创建对象时自动递增的公共(public)属性 我希望使用 autospec=T
我有这个工厂: Factory.define :email_address do |e| e.sequence(:address) { |n| "factory_#{n}@example.com"
试图围绕 Spec 和 Autospec 之间的区别进行思考。他们似乎差不多。具体来说,如果您查看 mock.patch 装饰器。 有人可以解释什么时候使用哪个? https://docs.pytho
http://lists.idyll.org/pipermail/testing-in-python/2013-March/005467.html 我昨天发布了这个。我无意匆忙和重复。但我想尽快解决这
我总是运行 autospec 以同时运行功能和 RSpec,但在我的本地计算机上运行所有功能通常很耗时。我会在提交代码之前运行每个功能。 我想在 autospec 命令中传递参数。 autospec
我是一名优秀的程序员,十分优秀!