mock.call_count的线程安全版本

jul*_*enc 7 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()
Run Code Online (Sandbox Code Playgroud)

此代码生成以下输出:

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
Run Code Online (Sandbox Code Playgroud)

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

jul*_*enc 6

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

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()
Run Code Online (Sandbox Code Playgroud)

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