首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >mock.patch与多处理

mock.patch与多处理
EN

Stack Overflow用户
提问于 2020-12-29 13:32:57
回答 1查看 854关注 0票数 0

我很难在多处理环境中使用mock.patch,而没有多处理的mock.patch工作得很好。文件名:test_mp.py

代码语言:javascript
复制
import multiprocessing
import mock

def inner():
    return sub()

def sub():
    return "abc"

def test_local():
    assert inner()=="abc"

def test_mp():    
    with multiprocessing.Pool() as pool:
        assert pool.apply(inner,args=[])=='abc'

def test_mock():    
    with mock.patch('test_mp.sub', return_value='xxx') as xx:
        assert inner()=="xxx"
        xx.assert_called_once()

def test_mp_mock():    
    with multiprocessing.Pool() as pool:
        with mock.patch('test_mp.sub', return_value='xyz') as xx:
            assert pool.apply(inner,args=[])=='xyz'
            xx.assert_called_once()

  • Test test_localtest_mocktest_mock完成了

test_mp_mock测试失败

代码语言:javascript
复制
=================================== FAILURES ===================================
_________________________________ test_mp_mock _________________________________

    def test_mp_mock():
        with multiprocessing.Pool() as pool:
            with mock.patch('test_mp.sub', return_value='xyz') as xx:
>               assert pool.apply(inner,args=[])=='xyz'
E               AssertionError: assert 'abc' == 'xyz'
E                 - abc
E                 + xyz

projects/mfhealth/test_mp.py:25: AssertionError

更新:

https://medium.com/uckey/how-mock-patch-decorator-works-in-python-37acd8b78ae的基础上,在sharedmock https://github.com/elritsch/python-sharedmock的帮助下,我能够更进一步,但仍未完成。

我将test_mp.py扩展为

代码语言:javascript
复制
from sharedmock.mock import SharedMock

def inner2(sm):
    with mock.patch('test_mp.sub', sm) as xx:
        return inner()


def test_mp_smock():
    with multiprocessing.Pool() as pool:
        sm=SharedMock()
        sm.return_value="xyz"
        with mock.patch('test_mp.sub', sm) as xx:
            assert pool.apply(inner2,args=[sm])=='xyz'
            assert xx.call_count == 1

def test_mp_mock2():
    with multiprocessing.Pool() as pool:
        sm=mock.Mock()
        sm.return_value="xyz"
        print(f"before patch {sub}, {locals()}")
        with mock.patch('test_mp.sub', sm) as xx:
            print(f"after patch {sub}")
            assert pool.apply(inner2,args=[sm])=='xyz'
            assert xx.call_count == 1

取得了以下结果:

  • test_mp_smock_pickle.PicklingError: Can't pickle <class 'mock.mock.Mock'>: it's not the same object as mock.mock.Mock

完成successfully.

  • test_mp_mock2失败

test_mp_smock的主要缺点是必须引入一种新的方法inner2来通过mock.patch激活补丁。任何关于如何将补丁从test_mp_smock传播到正在测试的代码而不引入包装器方法inner2的想法,因为我不能覆盖。

代码语言:javascript
复制
pool.apply(inner,args=[])
EN

回答 1

Stack Overflow用户

发布于 2020-12-29 22:20:45

终于,我让它起作用了。

SharedMock并不像Mock那样灵活。缺少assert_called_once_with,.,但是可以设置返回的值或检查调用的次数或其参数。

代码语言:javascript
复制
import multiprocessing
import mock
from sharedmock.mock import SharedMock


def inner():
    return sub(x="xxx")

def sub(x=""):
    return f"abc"

def fun_under_test():
    with multiprocessing.Pool() as pool:
        assert pool.apply(inner,args=[])=='xyz'

def test_final():
    sm=SharedMock()
    sm.return_value="xyz"
    with mock.patch('test_mp.sub', sm) as xx:
        fun_under_test()
        assert xx.call_count == 1 #number of calls of sub function
        assert xx.mock_calls[0][2]['x']=="xxx" # value of parameters ie sub(x="xxx")
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65492977

复制
相关文章

相似问题

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