无法在 Windows 上使用 Python 模拟 os 名称
Unable to mock os name with Python on Windows
我有以下方法:
class Controls:
def check_os(self) -> None:
if os.name != "posix":
raise OSError
我正在尝试这样测试它:
import pytest
@pytest.fixture
def name_mock(mocker):
return mocker.patch("path_to_module.controls.os.name", return_value="posix")
def test_check_os_fail(name_mock):
controls = Controls()
controls.check_os()
但随后出现以下错误:
platform win32 -- Python 3.9.0, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
plugins: cov-2.11.1, mock-3.5.1
collected 57 items / 56 deselected / 1 selected
tests\test_controls.py
INTERNALERROR> Traceback (most recent call last):
...
NotImplementedError: cannot instantiate 'PosixPath' on your system
到底发生了什么?
这里发生的是 pytest
内部使用 pathlib.Path
对象,该对象在初始化时要求 os.name
定义要使用的 Path
实现。 Path
、PosixPath
和WindowsPath
有两种内部实现,只在各自的系统下可用。当您通过修补 os.name
伪造 Posix 系统时,它会尝试实例化 PosixPath
对象,该对象未在 Windows.
下定义
在这种情况下你可以做的是将 os.name
包装在你自己的函数中,例如类似于:
import os
def os_name():
return os.name
class Controls:
def check_os(self) -> None:
if os_name != "posix":
raise OSError
并在您的测试中修补该功能:
@pytest.fixture
def name_mock(mocker):
return mocker.patch("path_to_module.controls.os_name", return_value="posix")
这样你只修补你应该修补的调用,而不影响其他也使用 os.name
.
的代码
我有以下方法:
class Controls:
def check_os(self) -> None:
if os.name != "posix":
raise OSError
我正在尝试这样测试它:
import pytest
@pytest.fixture
def name_mock(mocker):
return mocker.patch("path_to_module.controls.os.name", return_value="posix")
def test_check_os_fail(name_mock):
controls = Controls()
controls.check_os()
但随后出现以下错误:
platform win32 -- Python 3.9.0, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
plugins: cov-2.11.1, mock-3.5.1
collected 57 items / 56 deselected / 1 selected
tests\test_controls.py
INTERNALERROR> Traceback (most recent call last):
...
NotImplementedError: cannot instantiate 'PosixPath' on your system
到底发生了什么?
这里发生的是 pytest
内部使用 pathlib.Path
对象,该对象在初始化时要求 os.name
定义要使用的 Path
实现。 Path
、PosixPath
和WindowsPath
有两种内部实现,只在各自的系统下可用。当您通过修补 os.name
伪造 Posix 系统时,它会尝试实例化 PosixPath
对象,该对象未在 Windows.
在这种情况下你可以做的是将 os.name
包装在你自己的函数中,例如类似于:
import os
def os_name():
return os.name
class Controls:
def check_os(self) -> None:
if os_name != "posix":
raise OSError
并在您的测试中修补该功能:
@pytest.fixture
def name_mock(mocker):
return mocker.patch("path_to_module.controls.os_name", return_value="posix")
这样你只修补你应该修补的调用,而不影响其他也使用 os.name
.