如何模拟你的功能? 我不知道如何在Python中模拟我的函数,我试着寻找一些代码,但似乎没有用,考虑一下这个布局: | project.py | tests.py
project.py: tests.py: 因此,python3 tests.py:如何模拟你的功能? 我不知道如何在Python中模拟我的函数,我试着寻找一些代码,但似乎没有用,考虑一下这个布局: | project.py | tests.py,python,Python,project.py: tests.py: 因此,python3 tests.py: 正如您所看到的,test\u os\u urandom\u mocked是可以的,但是我尝试模拟foobar函数的所有其他测试都失败了,不知道为什么,请任何人解释一下是否可以这样做?您可以通过模块引用修补过的函数来实现这一点: import unittest from unittest.mock import patch import os import project def os_urandom_mock
正如您所看到的,test\u os\u urandom\u 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一个字符串时,它将替换该路径上的引用。这种行为得到了很好的证明。谢谢你的链接
按照现在的代码,测试文件中的foobar引用了原始函数,因为您是在补丁安装到位之前导入的。相反,如果您通过模块引用它,您将始终使用模块的引用
或者,您可以按照注释中的建议执行操作,并让修补程序替换当前范围内的引用,而不是原始模块中的引用:
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:
project.py:
tests.py:
您可以通过模块参考已修补的功能来实现这一点:
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一个字符串时,它将替换该路径上的引用。这种行为得到了很好的证明。谢谢你的链接
按照现在的代码,测试文件中的foobar引用了原始函数,因为您是在补丁安装到位之前导入的。相反,如果您通过模块引用它,您将始终使用模块的引用
或者,您可以按照注释中的建议执行操作,并让修补程序替换当前范围内的引用,而不是原始模块中的引用:
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:
project.py:
tests.py:
事实上,我真正想做的是模拟post_save django信号,所以事实上,我真正想做的是模拟post_save django信号,所以尝试返回值而不是副作用。同样的结果,无!='模拟“尝试返回值而不是副作用。结果相同,无!=”mocked'这将起作用,但您不需要通过模块引用函数。这意味着您必须将所有的导入都更改为模块导入以进行任何模拟。您需要通过查找对象的位置来引用它。例如,在他最初的测试中,我非常确定他可能会使用@patch'foobar,并且它会起作用。更多信息:谢谢。我不知道你不需要参考模块就可以做到这一点。在这种情况下,你实际上不能用这种方式修补“foobar”,但这仅仅是因为修补程序的工作方式。它需要一个指向要替换的引用的完全限定路径。我会继续更新我的答案,并附上一些关于这个的注释。啊,你说得对。修补程序需要点分隔的模块字符串。但是,试试这个:@patch\uuuu name\uuuuu+'.foobar',它可以修补您当前所在模块中的内容。干杯这将起作用,但您不需要通过模块引用函数。这意味着您必须将所有的导入都更改为模块导入以进行任何模拟。您需要通过查找对象的位置来引用它。例如,在他最初的测试中,我非常确定他可能会使用@patch'foobar,并且它会起作用。更多信息:谢谢。我不知道你不需要参考模块就可以做到这一点。在这种情况下,你实际上不能用这种方式修补“foobar”,但这仅仅是因为修补程序的工作方式。它需要一个指向要替换的引用的完全限定路径。我会继续更新我的答案,并附上一些关于这个的注释。啊,你说得对。修补程序需要点分隔的模块字符串。但是,试试这个:@patch\uuuu name\uuuuu+'.foobar',它可以修补您当前所在模块中的内容。干杯这可能满足了您的特定需求,但并不是对您实际问题的回答\这可能满足了您的特定需求,但并不是对您实际问题的回答\
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()
def baz():
return 'baz'
from asdf import baz
def foobar():
return baz()
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()