- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个函数,比方说 def temp
.我正在通过以下方式 mock 它:
msg = "Mocked!!!!!!!"
@mock.patch.object(Someothermodule.Someclass,'Somefunction',create=True,side_effect=Error(Error.something,msg))
def temp(self,mock_A):
这是一个巨大的项目,所以不能在这里发布细节。但是正在发生的是函数 temp
确实被 mock 了,我确实得到了正确的信息,但后来我得到了stop called on unstarted patcher
程序失败了。这里有什么解决方法吗,它以某种方式禁用了 _exit
的 mock
或任何其他方法。我猜内容在某种程度上不足以创建整个场景,但这是我能做的最好的。
此外,如果我不提供 mock_A
会怎样功能def temp
.在这种情况下补丁的作用是什么?
编辑:
我有一个解决方法,其中我定义了我的补丁如下:
@mock.patch.object(Someothermodule.Someclass,'Somefunction',create=True,some_function)
def temp(self):
现在的问题是
1) 当我使用 side_effect
时或 return_value
我必须提供 mock_object
到装饰器后面的函数。
2) 当我只是使用函数而不是 side_effect
时,我不需要为装饰器后面的函数提供模拟对象..
所以,
When we dont pass mock_obj,do all the function know about the patch?how exactly is this working?What is the difference between the scenario wherein we have to explicitly pass mock_object and wherein we dont have to?
(请注意,这与 new_callable
的定义中的 patch
有关。)
最佳答案
关于 patch
的基本信息:
Inside the body of the function or with statement, the target is patched with a new object. When the function/with statement exits the patch is undone.
If
new
is omitted, then the target is replaced with aMagicMock
. Ifpatch()
is used as a decorator and new is omitted, the created mock is passed in as an extra argument to the decorated function. Ifpatch()
is used as a context manager the created mock is returned by the context manager.
第一个告诉我们补丁在函数体(装饰器案例)中充当上下文管理器。第二个告诉你是否不指定 new
参数(第一个在 patch
类函数中 targeting arguments 之后)补丁创建一个新的 MagicMock()
对象来修补目标,创建的模拟作为额外参数传递给装饰函数。
这解释了问题的最后一部分,因为
@mock.patch.object(Someothermodule.Someclass,'Somefunction',create=True,some_function)
def temp(self):
你将 Someothermodule.Someclass.Somefunction
替换为 some_function
object 并且 patch
装饰器不需要通过它到 temp
。
现在回到问题的根源:stop called on unstarted patcher
错误消息。
这意味着您尝试多次删除补丁。怎么可能?
如果您查看 mock.py
代码你可以很容易地理解补丁不支持补丁堆栈,它被设计为每个上下文只执行一次。换句话说,如果您尝试修补已在您的上下文中修补的内容,您将得到相同的错误。在答案的最后,我提供了一个生成错误的合成示例。
在没有看到您的代码的情况下,如果您不使用模拟而是通过函数修补您的方法,我只能猜测和推测为什么您的问题seams 已修复。恕我直言,它的工作只是偶然,你在玩某种竞争条件。
我能做的是为您提供一种方法来解决您的问题,并提供一个良好的解决方法。
如果您在补丁中多次调用 __exit__
,则只需使用 patch
作为上下文管理器并覆盖 __exit__
。一种未经测试的方法可能是:
def my_wrapper(f):
count = 0
@functools.wraps(f)
def exit(*args, **kwargs):
count += 1
print ("EXIT CALL {}".format(count))
f(*args, **kwargs)
def temp(self):
patcher = mock.patch.object(Someothermodule.Someclass,'Somefunction',create=True,side_effect=Error(Error.something,msg))
patcher.__exit__ = my_wrapper(patcher.__exit__)
with patcher as mock_A:
#... your stuff
最后是解决方法(仅在您找不到任何方法来修复双重调用时使用)
class MyStackPatch():
def __init__(p):
self._patcher = p
self._count = 0
self._lock = threading.RLock()
def __enter__(self):
with self._lock:
if not self._count:
self._patcher.start()
self._count += 1
def __exit__(self, *exc_info):
with self._lock:
self._count -= 1
if not self._count:
self._patcher.stop()
def temp(self):
patcher = mock.patch.object(Someothermodule.Someclass,'Somefunction',create=True,side_effect=Error(Error.something,msg))
with MyStackPatch(patcher) as mock_A:
#... your stuff
扩展它并编写装饰器也很容易...但我认为这足以解决问题。
这是一个生成 stop called on unstarted patcher
错误消息的合成示例。要生成它,我们必须在补丁上下文中再次调用补丁。我们可以通过递归或线程来完成,递归在这种情况下真的很奇怪。
target
调用 patched 方法并启动一个也调用 t()
的新线程。我使用了 Event()
来强制错误并使竞争条件始终为真。
import threading
from mock import patch
def somemethod():
pass
e = threading.Event()
@patch("__main__.somemethod")
def t(state,m):
if state:
e.set()
while e.is_set():
e.wait(.5)
somemethod()
def target():
threading.Thread(target=t,args=(True,)).start()
while not e.is_set():
e.wait(.1)
t(False)
e.clear()
target()
/usr/bin/python2.7 /home/damico/PycharmProjects/untitled1/mock_and_thread.py
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "/usr/local/lib/python2.7/dist-packages/mock.py", line 1214, in patched
patching.__exit__(*exc_info)
File "/usr/local/lib/python2.7/dist-packages/mock.py", line 1376, in __exit__
raise RuntimeError('stop called on unstarted patcher')
RuntimeError: stop called on unstarted patcher
关于Python 模拟错误 : stop called on unstarted patcher,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29065512/
我经常使用stop Fortran 中固有的因各种原因停止执行(主要是在测试失败后)。 program test1 stop end program 除了停止程序执行之外什么都不做。 prog
我想编写一个函数,用字符 e 替换所有出现的字符 c。这些功能似乎正在发挥作用。然而,主要是,我希望能够重复输入一个字符串,扫描要替换的字符,扫描要替换的字符,并打印之前和之后的内容,直到输入的字符串
在 powershell 中,我看到了多种停止服务的方法 更现代的方式 Stop-Service wuauserv 而更传统的方式 NET STOP WUAUSERV 遗留方式 is much mor
所以问题是我需要一个正则表达式,只有当它的 stop 也意味着 stopp 或 sstoooppp 时,它才会匹配第二个单词> 后跟一个空格。我需要得到这个词,我找不到任何正则表达式来做到这一点,因为
我正在做这样的事情 http://jsfiddle.net/8ErSL/2/ 当您将鼠标悬停在任何文本框 (div) 上时,其中会出现一个小图标。 我想阻止图标的淡入淡出效果在我不小心将鼠标悬停在 d
这段代码在 Debug模式下工作得很好,但当不是 Debug模式时它总是抛出运行时异常。 mMediaRecorder.stop(); 根据 Java 文档: Stops recordin
这是我的full code ,这里是my project ,当我在 #onCreate 中使用 MediaRecorder#stop 时,它会引发 java.lang.RuntimeException
我使用 C# 编写了一个库并在 PowerShell 脚本中使用它。 C# 库将大量数据加载到数据库中。我正在使用 Start-Job 来启动该过程,并且我正在监视一个文件是否有错误。 但是,我发现即
我正在尝试编写以下问题的代码: 在 a0, a1, ..., an 处有 n 个酒店,使得 0 dp(k)+(ai-ak)^2) dp(i) = dp(k)+(ai-ak)^2)
我有一个简单的测试,我使用 run_forever 方法运行 Python asyncio 事件循环,然后立即在另一个线程中停止它。但是,事件循环似乎并没有终止。我有以下测试用例: import as
我有以下情况: 专用租赁 m4.large 运行 RHEL6 的 EC2 实例 使用 AWS 控制台手动启动它效果很好 尝试启动它的 Lambda 函数(用 Java 编写)失败,因为实例状态为:已停
我正在使用 Yajsw 将我的应用程序作为守护进程运行。 对于状态调用,我希望看到“正在运行”或“已停止”,但我收到的消息如下所示 SW043305-SRV01:/etc/init.d # ./tes
在 Tomcat 或 TomEE 中,service tomcat start/stop 和 ./catalina.sh run/stop 有什么区别? 他们做的事情完全一样吗? 最佳答案 catal
我正在尝试使用 C++ 和 OpenGL/GLUT 制作一个 Snake 克隆。然而,我一直在编程允许输入 Action 之间的短时间间隔时遇到问题。我已经尝试了一些计时方法,最后我为它创建了一个类(
问题: org.apache.catalina.loader.WebappClassLoader - The web application [/…] appears to have started
我正在尝试以下实验: 我有两个QpushButtons,比如PushA 和PushB。现在 PushA 在 QHBoxLayout 中,PushB 也在它自己的 QHBoxLayout 中。这两个水平
我已经在我的 windows 10 机器上安装了 Docker for Windows。当我尝试从“windows 容器”“切换到 linux 容器”时,出现错误。 Unable to start:
我在我的应用程序中集成了摄像头。当用户单击捕获按钮时,我隐藏了工具栏,以便摄像头预览屏幕尺寸增加。这会导致应用程序在停止在线录制时崩溃 - mMediaRecorder.stop(); 。 java.
运行功能时 stop("m Sys.setenv(LANG = "fr") > 2 + x Erreur : objet 'x' introuvable > Sys.setenv(LANG = "en
我有一个 Windows 10 内部版本,我正在尝试安装 cpriego/valet-linux使用 wsl2 我已经安装了 composer、php 和所有其他的要求。 现在当我做 valet st
我是一名优秀的程序员,十分优秀!