首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Mock线程调用pytest-mock

Mock线程调用pytest-mock
EN

Stack Overflow用户
提问于 2020-06-15 06:08:57
回答 1查看 293关注 0票数 1

我有一个简单的代码库,如下所示:

代码语言:javascript
运行
复制
import threading
import time

class Demo:
    def __init__(self):
        self._run_thread = False

    def start(self):
        if not self._run_thread:
            print("Thread has not run")
            threading.Thread(target=self.counter, args=(20, )).start()
            return 20
        else:
            print("Thread has run")
            return None


    def counter(self, value):
        self._run_thread = True
        for i in range(value):
            print(f"Inside counter with value {i}")
            time.sleep(3)



if __name__ == "__main__":
    d = Demo()
    d.start()
    d.start()

由于设置了标志(_run_thread),因此第一次调用start函数时,线程将运行,而下一次调用该函数时,线程将不再运行。

代码本身运行得非常好。

但是,当我尝试对此代码运行测试时,它并不能像预期的那样工作。下面是我的测试代码:

代码语言:javascript
运行
复制
import app

def dummy_counter(self, value):
    self._run_thread = True

def test_app_start_function_runs_well(mocker):
    d = app.Demo()
    mocker.patch.object(
        d,
        "counter",
        dummy_counter
    )
    d.start()
    result = d.start()
    assert result is None

因此,由于我实际上不希望循环,所以我只想模拟counter函数,然后在它内部设置标志,这样实际的线程就不会运行。

我看到了下面的错误。

代码语言:javascript
运行
复制
(roughwork) ➜  threads git:(master) ✗ pytest
============================================================ test session starts ============================================================
platform linux -- Python 3.7.6, pytest-5.4.3, py-1.8.1, pluggy-0.13.1
rootdir: /home/subhayan/Codes/Test/Python-remote/threads
plugins: mock-3.1.1
collected 1 item                                                                                                                            

test_app.py Exception in thread Thread-2:
Traceback (most recent call last):
  File "/home/subhayan/anaconda3/envs/roughwork/lib/python3.7/threading.py", line 926, in _bootstrap_inner
    self.run()
  File "/home/subhayan/anaconda3/envs/roughwork/lib/python3.7/threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
TypeError: dummy_counter() missing 1 required positional argument: 'value'

F                                                                                                                         [100%]

================================================================= FAILURES ==================================================================
____________________________________________________________ test_app_runs_well _____________________________________________________________

mocker = <pytest_mock.plugin.MockFixture object at 0x7f922c05ee90>

    def test_app_runs_well(mocker):
        d = app.Demo()
        mocker.patch.object(
            d,
            "counter",
            dummy_counter
        )
        d.start()
        result = d.start()
>       assert result is None
E    assert 20 is None

test_app.py:15: AssertionError
----------------------------------------------------------- Captured stdout call ------------------------------------------------------------
Thread has not run
Thread has not run
----------------------------------------------------------- Captured stderr call ------------------------------------------------------------
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/home/subhayan/anaconda3/envs/roughwork/lib/python3.7/threading.py", line 926, in _bootstrap_inner
    self.run()
  File "/home/subhayan/anaconda3/envs/roughwork/lib/python3.7/threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
TypeError: dummy_counter() missing 1 required positional argument: 'value'

========================================================== short test summary info ==========================================================
FAILED test_app.py::test_app_runs_well - assert 20 is None

我不知道我错在哪里。任何线索我都会非常感激。

EN

回答 1

Stack Overflow用户

发布于 2021-09-09 10:03:09

你几乎每件事都做对了。唯一的问题是,self.counter是一个绑定到实例的方法,所以self中填充的是您正确的d实例。但是,dummy_counter没有绑定-因此它不会自动获取第一个参数,因此您需要提供它。

一种方法是使用分部函数,如下所示:

代码语言:javascript
运行
复制
from functools import partial

import app


def dummy_counter(self, value):
    self._run_thread = True


def test_app_start_function_runs_well(mocker):
    d = app.Demo()
    dummy_for_d = partial(dummy_counter, d)  # fills the first parameter with 'd'

    mocker.patch.object(
        d,
        "counter",
        dummy_for_d
    )
    d.start()
    result = d.start()
    assert result is None
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62378800

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档