python - 无法在 Windows 上使用 Python 模拟操作系统名称
问题描述
我有以下方法:
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
,它们仅在各自的系统下可用。当您通过修补来伪造 Posix 系统时,它会尝试实例化一个未在 Windows 下定义的对象。PosixPath
WindowsPath
os.name
PosixPath
在这种情况下,您可以做的是包装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
.
推荐阅读
- java - 无法在使用 selenium 的动态加载网页中滚动到页面底部
- azure-devops - 从迭代中获取所有项目
- html - html css更改某行中列的宽度
- jupyter-notebook - jupyter lab:区分大小写的文本搜索
- flutter - 如何强制 Flutter 应用向服务器请求新数据?
- reactjs - setState 没有被调用 onClick
- algorithm - 使用堆排序,追加一个数组元素
- php - {"status":"400","message":"无法使用提供的信息注册"}
- java - Java Arraylist.retainAll() 返回意外的空列表
- python - 如何使用 numba 加速具有不同维度向量的 numpy.ndarray?