python - mock.call_count 的线程安全版本

标签 python multithreading unit-testing mocking

看起来 Mock.call_count不能与线程一起正常工作。例如:

import threading
import time
from mock import MagicMock


def f():
    time.sleep(0.1)

def test_1():
    mock = MagicMock(side_effect=f)
    nb_threads = 100000
    threads = []
    for _ in range(nb_threads):
        thread = threading.Thread(target=mock)
        threads.append(thread)
        thread.start()

    for thread in threads:
        thread.join()

    assert mock.call_count == nb_threads, mock.call_count

test_1()

此代码产生以下输出:

Traceback (most recent call last):
  File "test1.py", line 24, in <module>
    test_1()
  File "test1.py", line 21, in test_1
    assert mock.call_count == nb_threads, mock.call_count
AssertionError: 99994

有没有一种方法可以在代码的多线程部分中使用 call_count(或类似的)?我想避免自己重写 MagicMock...

最佳答案

我最终通过使用一个链接到副作用方法的计数器和一个锁让它工作。

import threading
import time
from mock import MagicMock

lock_side_effect = threading.Lock()

def f():
    with lock_side_effect:
        f.call_count += 1
    time.sleep(0.1)

f.call_count = 0

def test_1():
    mock = MagicMock(side_effect=f)
    nb_threads = 100000
    threads = []
    for _ in range(nb_threads):
        thread = threading.Thread(target=mock)
        threads.append(thread)
        thread.start()

    for thread in threads:
        thread.join()

    assert f.call_count == nb_threads, f.call_count

test_1()

因此,我正在计算 f 而不是 mock 的调用次数,但结果符合预期。

关于python - mock.call_count 的线程安全版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39332139/

相关文章:

javascript - mocha done() 和 async await 的矛盾问题

python - 在使用 pytest 运行测试之前执行健全性检查

python:不同包下同名的两个模块和类

c# - 如果我在整个运行过程中都需要一次性用品怎么办?

python - 如何使用 Python 的 unittest 测试已引发警告?

java - PowerMock和EasyMock方法模拟问题

python - ffmpeg-python 尝试保存为 mp4 时输出黑屏

python - 将 Pandas 数据框中具有不同日期的较早行的值连接起来

linux - 线程间的上下文切换

c++ - QSystemSemaphore::acquire() 中止