gpt4 book ai didi

python - 如何模拟你的功能?

转载 作者:行者123 更新时间:2023-11-30 22:17:29 25 4
gpt4 key购买 nike

我不知道如何在 python 中模拟我的函数,我尝试寻找一些代码,但似乎都不起作用,请考虑以下布局:

| project.py
| tests.py

project.py:

def foobar():
return

tests.py:

import unittest
from unittest.mock import patch
import os

from project import foobar

def os_urandom_mock():
return 'mocked'

def foobar_mock():
return 'mocked'


class TestProject(unittest.TestCase):

# mocked os.urandom worked well
@patch('os.urandom', side_effect=os_urandom_mock)
def test_os_urandom_mocked(self, os_urandom_mocked):
self.assertEqual(os.urandom(), 'mocked')

# but this doesn't
@patch('project.foobar', side_effect=foobar_mock)
def test_foobar_mocked(self, foobar_mocked):
self.assertEqual(foobar(), 'mocked')

# and this also doesn't work
@patch('project.foobar')
def test_foobar_mocked_another(self, foobar_mocked):
foobar_mocked.return_value = 'mocked'
self.assertEqual(foobar(), 'mocked')

# and this also doesn't work
def test_foobar_mocked_last_try(self):
with patch('project.foobar') as foobar_mocked:
foobar_mocked.return_value = 'mocked'
self.assertEqual(foobar(), 'mocked')

unittest.main()

所以,python3测试.py:

======================================================================
FAIL: test_foobar_mocked (__main__.TestProject)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Python36\lib\unittest\mock.py", line 1179, in patched
return func(*args, **keywargs)
File "tests.py", line 24, in test_foobar_mocked
self.assertEqual(foobar(), 'mocked')
AssertionError: None != 'mocked'

======================================================================
FAIL: test_foobar_mocked_another (__main__.TestProject)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Python36\lib\unittest\mock.py", line 1179, in patched
return func(*args, **keywargs)
File "tests.py", line 30, in test_foobar_mocked_another
self.assertEqual(foobar(), 'mocked')
AssertionError: None != 'mocked'

======================================================================
FAIL: test_foobar_mocked_last_try (__main__.TestProject)
----------------------------------------------------------------------
Traceback (most recent call last):
File "tests.py", line 35, in test_foobar_mocked_last_try
self.assertEqual(foobar(), 'mocked')
AssertionError: None != 'mocked'

----------------------------------------------------------------------
Ran 4 tests in 0.002s

FAILED (failures=3)

如您所见,test_os_urandom_mocked 没问题,但是我尝试模拟我的 foobar 函数的所有其他测试都失败了,不知道为什么,任何人都可以吗?请解释一下是否可以这样做?

最佳答案

您可以通过模块引用修补后的函数来完成此工作:

import unittest
from unittest.mock import patch
import os
import project

def os_urandom_mock():
return 'mocked'

def foobar_mock():
return 'mocked'


class TestProject(unittest.TestCase):

@patch('os.urandom', side_effect=os_urandom_mock)
def test_os_urandom_mocked(self, os_urandom_mocked):
self.assertEqual(os.urandom(), 'mocked')

@patch('project.foobar', side_effect=foobar_mock)
def test_foobar_mocked(self, foobar_mocked):
self.assertEqual(project.foobar(), 'mocked')

@patch('project.foobar')
def test_foobar_mocked_another(self, foobar_mocked):
foobar_mocked.return_value = 'mocked'
self.assertEqual(project.foobar(), 'mocked')

def test_foobar_mocked_last_try(self):
with patch('project.foobar') as foobar_mocked:
foobar_mocked.return_value = 'mocked'
self.assertEqual(project.foobar(), 'mocked')

unittest.main()

这里要注意的关键是,当您给 patch 一个字符串时,它会替换该路径上的引用。这种行为得到了很好的证明 here 。 (感谢 wholevinski 提供链接。)

根据您现在的代码,测试文件中的 foobar 引用原始函数,因为您在补丁到位之前导入了它。相比之下,如果您通过模块引用它,则将始终使用模块的引用。

或者,您可以执行 wholevinski 操作在评论中建议,并让您的补丁替换当前范围内的引用,而不是其原始模块中的引用:

import unittest
from unittest.mock import patch
import os
from project import foobar

def os_urandom_mock():
return 'mocked'

def foobar_mock():
return 'mocked'


class TestProject(unittest.TestCase):
@patch(__name__ + '.foobar', side_effect=foobar_mock)
def test_foobar_mocked(self, foobar_mocked):
self.assertEqual(foobar(), 'mocked')

@patch(__name__ + '.foobar')
def test_foobar_mocked_another(self, foobar_mocked):
foobar_mocked.return_value = 'mocked'
self.assertEqual(foobar(), 'mocked')

def test_foobar_mocked_last_try(self):
with patch(__name__ + '.foobar') as foobar_mocked:
foobar_mocked.return_value = 'mocked'
self.assertEqual(foobar(), 'mocked')

unittest.main()

请注意,在大多数情况下,您将修补被测试模块导入的某些内容,而不是直接在测试中调用修补的函数。在这种情况中,事情往往会变得更加清晰:

asdf.py:

def baz():
return 'baz'

project.py:

from asdf import baz

def foobar():
return baz()

测试.py:

import unittest
from unittest.mock import patch
import os
from project import foobar

def baz_mock():
return 'mocked'

class TestProject(unittest.TestCase):
@patch('project.baz', side_effect=baz_mock)
def test_foobar_mocked(self, foobar_mocked):
self.assertEqual(foobar(), 'mocked')

@patch('project.baz')
def test_foobar_mocked_another(self, baz_mocked):
foobar_mocked.return_value = 'mocked'
self.assertEqual(foobar(), 'mocked')

def test_foobar_mocked_last_try(self):
with patch('project.baz') as baz_mocked:
foobar_mocked.return_value = 'mocked'
self.assertEqual(foobar(), 'mocked')

unittest.main()

关于python - 如何模拟你的功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49652184/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com