Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 通过替换类来模拟类_Python_Unit Testing_Testing_Mocking_Pytest - Fatal编程技术网

Python 通过替换类来模拟类

Python 通过替换类来模拟类,python,unit-testing,testing,mocking,pytest,Python,Unit Testing,Testing,Mocking,Pytest,假设你有一个模块 from module.my_module import Foo def my_function(): foo = Foo() return whatewer_can_happen(foo) 你想这样测试吗 class TestFoo: def __init__(): pass def dont_care(): return 9 def test_something(): with m

假设你有一个模块

from module.my_module import Foo


def my_function():
    foo = Foo()
    return whatewer_can_happen(foo)
你想这样测试吗

class TestFoo:
    def __init__():
         pass
    
    def dont_care():
        return 9


def test_something():
    with mock.patch('tested_module.Foo') as mocked_class:
        mocked_class.side_effect = lambda *args: TestFoo(*args)
        assert tested_module.my_function() == 'not important'
基本上就像您想要注入TestFoo来代替Foo一样 (示例不适用于ofc,仅用于说明)

如何在不更改测试代码的情况下模拟测试模块中的
Foo
类?如果不可能,为什么python中的类与函数如此不同,以至于无法模拟它们

我不是在寻找不同的方法(工厂函数/直接模拟类函数等)


在某些情况下,编写模拟类并将它们注入测试模块中会很有帮助(而且可读性更高)

通过将其传递给
mock.patch
调用,您始终可以提供自己的模拟,而不是默认的
MagicMock
实例:

def test_something():
使用mock.patch('tested_module.Foo',TestFoo):
断言已测试的\u模块。我的\u函数()=='不重要'
请注意,此处不能使用
副作用
,因为您的新对象不是
Mock
对象。此外,如果使用decorator版本,则模拟将不会有额外的参数:

@mock.patch('tested_module.Foo',TestFoo):
def test_something():
断言已测试的\u模块。我的\u函数()=='不重要'
以下是报告的相关部分:

如果省略了new,则如果修补对象是异步函数,则将目标替换为
AsyncMock
,否则替换为
MagicMock
。如果
patch()
用作修饰符,并且省略了new,则创建的mock将作为额外参数传递给修饰函数。如果
patch()
用作上下文管理器,则上下文管理器将返回创建的模拟


您可以通过mock.patch('tested_module.Foo',TestFoo')传递模拟类作为替换:
。检查
mock.patch
的文档,特别是
new
new\u callable
参数。如果您没有传递替换对象,将创建一个
MagicMock
,但这只是默认值。@MrBean Bremen哦,对了,请阅读文档。。我在SO和google上找不到答案,你介意发布一个答案让我接受吗?