使用pytest模拟导入模块中包含的函数的行为
Mocking behavior of functions contained in imported module using pytest
假设我有两个文件 main.py
和 test_main.py
。 main.py
的内容是:
import os
print('script running', os.getcwd())
test_main.py
的内容是:
import pytest
import main
运行 pytest -s
returns 以下内容:
================================================= test session starts ==================================================
platform linux -- Python 3.8.6, pytest-6.2.3, py-1.10.0, pluggy-0.13.1
rootdir: /home/example_mocking
plugins: dash-1.20.0, anyio-2.2.0
collecting ... script running /home/example_mocking
collected 0 items
================================================ no tests ran in 0.01s =================================================
现在假设 main.py
已经由其他人提供给我,在我实现完整的测试覆盖率之前我不希望修改它。但是,我想修改 os.getcwd()
的行为,使其 returns “Hello” 而不是我当前的工作目录。
有没有一种方法可以在不修改 main.py
的情况下模拟 os
的行为,这样当我 运行 pytest -s
以下显示时?
================================================= test session starts ==================================================
platform linux -- Python 3.8.6, pytest-6.2.3, py-1.10.0, pluggy-0.13.1
rootdir: /home/example_mocking
plugins: dash-1.20.0, anyio-2.2.0
collecting ... script running Hello
collected 0 items
================================================ no tests ran in 0.01s =================================================
我建议重构您的脚本,使其不会对导入产生副作用——这些很难正确地修补和测试而不造成污染。
这是一个调整后的设置,它仍然有效,但更易于测试(您可以在我在这里整理的视频中找到有关此技术的更多信息:python cli tested with pytest)
# main.py
import os
def main() -> int:
print('script running', os.getcwd())
return 0
if __name__ == '__main__':
raise SystemExit(main())
# main_test.py
import os
from unittest import mock
import main
def test_main_prints_cwd(capsys):
# can adjust what `getcwd` returns
with mock.patch.object(os, 'getcwd', return_value='Hello'):
assert main.main() == 0 # can test the return value of your program
# can test what your program prints
out, err = capsys.readouterr()
assert out == 'script running Hello\n'
assert err == ''
假设我有两个文件 main.py
和 test_main.py
。 main.py
的内容是:
import os
print('script running', os.getcwd())
test_main.py
的内容是:
import pytest
import main
运行 pytest -s
returns 以下内容:
================================================= test session starts ==================================================
platform linux -- Python 3.8.6, pytest-6.2.3, py-1.10.0, pluggy-0.13.1
rootdir: /home/example_mocking
plugins: dash-1.20.0, anyio-2.2.0
collecting ... script running /home/example_mocking
collected 0 items
================================================ no tests ran in 0.01s =================================================
现在假设 main.py
已经由其他人提供给我,在我实现完整的测试覆盖率之前我不希望修改它。但是,我想修改 os.getcwd()
的行为,使其 returns “Hello” 而不是我当前的工作目录。
有没有一种方法可以在不修改 main.py
的情况下模拟 os
的行为,这样当我 运行 pytest -s
以下显示时?
================================================= test session starts ==================================================
platform linux -- Python 3.8.6, pytest-6.2.3, py-1.10.0, pluggy-0.13.1
rootdir: /home/example_mocking
plugins: dash-1.20.0, anyio-2.2.0
collecting ... script running Hello
collected 0 items
================================================ no tests ran in 0.01s =================================================
我建议重构您的脚本,使其不会对导入产生副作用——这些很难正确地修补和测试而不造成污染。
这是一个调整后的设置,它仍然有效,但更易于测试(您可以在我在这里整理的视频中找到有关此技术的更多信息:python cli tested with pytest)
# main.py
import os
def main() -> int:
print('script running', os.getcwd())
return 0
if __name__ == '__main__':
raise SystemExit(main())
# main_test.py
import os
from unittest import mock
import main
def test_main_prints_cwd(capsys):
# can adjust what `getcwd` returns
with mock.patch.object(os, 'getcwd', return_value='Hello'):
assert main.main() == 0 # can test the return value of your program
# can test what your program prints
out, err = capsys.readouterr()
assert out == 'script running Hello\n'
assert err == ''