gpt4 book ai didi

python - 杀死模拟对象 : A Python Story

转载 作者:太空狗 更新时间:2023-10-29 21:04:55 25 4
gpt4 key购买 nike

我在使用 Python mock 时遇到了麻烦,并且快要发疯了。由于担心因研究不足而投反对票,我推迟了这个问题。在过去的一周里,我总共花了 24 小时试图弄清楚如何完成这项工作,但我做不到。

我阅读了无数示例,并根据这些示例创建了这个示例。我知道模拟对象应该易于使用,但这花了太长时间。现在我没时间了。

我想在这里做两件简单的事情:

<强>1。在另一个函数中覆盖 request.ok 状态代码
<强>2。导致抛出 urllib2.HTTPError 异常

为方便起见,我已将这两个任务提炼成最简单的示例:

#ExampleModule.py

import requests
import urllib2

def hello_world():
try:
print "BEGIN TRY"
r = requests.request('GET', "http://127.0.0.1:80")
print r.ok

if r.ok:
print "PATCH 1 FAILED"
else:
print "PATCH 1 SUCCESSFUL"

except urllib2.HTTPError:
print "PATCH 2 SUCCESSFUL"
print "EXCEPTION 2 HIT\n"
else:
print "PATCH 2 FAILED\n"

#in TestModule.py

import mock
import ExampleModule

def test_function_try():
with mock.patch('ExampleModule.hello_world') as patched_request:
patched_request.requests.request.ok = False
result = ExampleModule.hello_world()
print result

def test_function_exception():
with mock.patch('ExampleModule.hello_world') as patched_exception:
patched_exception.urllib2.side_effect = HTTPError
result = ExampleModule.hello_world()
print result

test_function_try()
test_function_exception()

正常调用 hello_world() 输出:

BEGIN TRY
True
<Response [200]>

正常调用 test_function_try() 输出:

<MagicMock name='hello_world()' id='70272816'>
#From the "print result" inside test_function_try()

正常调用 test_function_exception() 输出:

<MagicMock name='hello_world()' id='62320016'>
#From the "print result" inside test_function_exception()

显然,我实际上并没有从 hello_world() 返回任何东西,所以看起来打补丁的对象是 hello_world() 函数,而不是请求或 urllib2 打补丁的模块。

应该注意的是,当我尝试使用“ExampleModule.hello_world.requests”或“ExampleModule.hello_world.urllib2”进行修补时,我收到一条错误消息,提示无法在 hello_world() 中找到它们

问题总结

  1. test_function_try() 和 test_function_exception() 这两个函数有什么问题?需要修改什么,以便我可以在 hello_world() 中手动分配 request.ok 的值,还可以手动引发异常 HTTPError 以便我可以测试该 block 中的代码...奖励积分解释“何时”抛出异常:一旦输入 try: 或调用请求时,或其他某个时间?
  2. 我一直担心的事情:我在 ExampleModule.py 中的打印语句是否会显示我的补丁和模拟测试是否有效,或者我是否必须使用断言方法来获取真相?当人们提到“使用断言来确定是否调用了实际的修补对象等”时,我不确定断言是否是必需的。或者这是为了方便/约定俗成/实用。

更新

根据@chepner 的建议,将补丁目标更改为 requests.request() 函数后,我收到以下输出:

BEGIN TRY
False
PATCH 1 SUCCESSFUL
PATCH 2 FAILED

BEGIN TRY
Traceback (most recent call last):
File "C:\LOCAL\ECLIPSE PROJECTS\MockingTest\TestModule.py", line 44, in <module>
test_function_exception()
File "C:\LOCAL\ECLIPSE PROJECTS\MockingTest\TestModule.py", line 19, in test_function_exception
ExampleModule.hello_world()
File "C:\LOCAL\ECLIPSE PROJECTS\MockingTest\ExampleModule.py", line 12, in hello_world
r = requests.request('GET', "http://127.0.0.1:8080")
File "C:\Python27\lib\site-packages\mock\mock.py", line 1062, in __call__
return _mock_self._mock_call(*args, **kwargs)
File "C:\Python27\lib\site-packages\mock\mock.py", line 1118, in _mock_call
raise effect
TypeError: __init__() takes exactly 6 arguments (1 given)

最佳答案

您不能在函数中模拟局部变量。您要模拟的是 requests.request 本身,这样当 hello_world 调用它时,会返回模拟对象,而不是实际发出 HTTP 请求。

import mock
import urllib2
import ExampleModule

def test_function_try():
with mock.patch('ExampleModule.requests.request') as patched_request:
patched_request.return_value.ok = False
ExampleModule.hello_world()

def test_function_exception():
with mock.patch('ExampleModule.requests.request') as patched_request:
patched_request.side_effect = urllib2.HTTPError
ExampleModule.hello_world()

test_function_try()
test_function_exception()

关于python - 杀死模拟对象 : A Python Story,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42927306/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com