Python 如何在方法中测试单个调用?
在下面的代码中,我想测试一下,如果Python 如何在方法中测试单个调用?,python,unit-testing,mocking,pytest,Python,Unit Testing,Mocking,Pytest,在下面的代码中,我想测试一下,如果config\u dir不存在,那么它将被创建 def\uu init__( self,config_dir:pathlib.Path=pathlib.Path().home()/“.config”/“moe”, ): “”“读取配置。 Args: config_dir:配置目录的路径。 """ self.config\u dir=config\u dir 如果不是self.config_dir.exists(): self.config_dir.mkdir(p
config\u dir
不存在,那么它将被创建
def\uu init__(
self,config_dir:pathlib.Path=pathlib.Path().home()/“.config”/“moe”,
):
“”“读取配置。
Args:
config_dir:配置目录的路径。
"""
self.config\u dir=config\u dir
如果不是self.config_dir.exists():
self.config_dir.mkdir(parents=True)
self.db_path:pathlib.path=self.config_dir/“library.db”
#初始化数据库
engine=sqlalchemy.create_引擎(“sqlite://”+str(self.db_路径))
library.Session.configure(bind=engine)
library.Base.metadata.create_all(引擎)#如果表不存在,则创建表
然而,我似乎不知道如何测试这部分代码。我试过了
def test_config_dir_dne(self, mocker):
"""We should create the config directory if it doesn't exist."""
fake_path = mocker.Mock()
moe.config.Config(fake_path)
fake_path.mkdir.assert_called_once_with(parents=True)
但是,pathlib不喜欢我在mock中使用特定的join操作符
> self.db_path: pathlib.Path = self.config_dir / "library.db"
E TypeError: unsupported operand type(s) for /: 'Mock' and 'str'
此外,我并不真正关心这部分测试代码,也不希望在最后创建引擎
如何在不运行任何其他代码的情况下测试并检查在我的
伪路径上调用了mkdirs
模仿更多。具体来说,您可以修补pathlib.Path
和sqlalchemy.create\u engine
以及不想测试的所有内容
使用依赖项注入,这样您就可以在不进行修补的情况下进行模拟。让构造函数获取抽象接口,然后让您的测试通过这些接口的虚拟版本
重新构造代码,使每个要单独测试的单元都有自己的功能。将要测试的逻辑(创建config dir)放入它自己的函数中,然后独立于构造函数对该函数进行单元测试
这里有三种通用方法:
模仿更多。具体来说,您可以修补pathlib.Path
和sqlalchemy.create\u engine
以及不想测试的所有内容
使用依赖项注入,这样您就可以在不进行修补的情况下进行模拟。让构造函数获取抽象接口,然后让您的测试通过这些接口的虚拟版本
重新构造代码,使每个要单独测试的单元都有自己的功能。将要测试的逻辑(创建config dir)放入它自己的函数中,然后独立于构造函数对该函数进行单元测试
在用于初始化数据库的函数\uuuuu init\uuuuuu>中添加一个附加参数。默认情况下,您将使用类本身提供的函数
def __init__(
self,
config_dir: pathlib.Path = pathlib.Path().home() / ".config" / "moe",
db_initializer=None
):
"""Read configuration.
Args:
config_dir: Path of the configuration directory.
"""
self.config_dir = config_dir
if not self.config_dir.exists():
self.config_dir.mkdir(parents=True)
self.db_path: pathlib.Path = self.config_dir / "library.db"
if db_initializer is None:
db_intializer = self._init_db
db_initializer(self.dp_path)
@staticmethod
def _init_db(p):
engine = sqlalchemy.create_engine("sqlite:///" + str(p))
library.Session.configure(bind=engine)
library.Base.metadata.create_all(engine)
def\uu init__(
自己
config_dir:pathlib.Path=pathlib.Path().home()/“.config”/“moe”,
db_初始值设定项=无
):
“”“读取配置。
Args:
config_dir:配置目录的路径。
"""
self.config\u dir=config\u dir
如果不是self.config_dir.exists():
self.config_dir.mkdir(parents=True)
self.db_path:pathlib.path=self.config_dir/“library.db”
如果db_初始值设定项为“无”:
db\u initializer=self.\u init\u db
db_初始值设定项(self.dp_路径)
@静力学方法
定义初始数据库(p):
engine=sqlalchemy.create_engine(“sqlite://“+str(p))
library.Session.configure(bind=engine)
library.Base.metadata.create_all(引擎)
当您测试该函数时,您将传递一个不执行任何操作的函数
def test_config_dir_dne(self, mocker):
"""We should create the config directory if it doesn't exist."""
fake_path = mocker.Mock()
moe.config.Config(fake_path, lambda p: None)
fake_path.mkdir.assert_called_once_with(parents=True)
def test\u config\u dir\u dne(自模拟):
“”“如果配置目录不存在,我们应该创建它。”“”
fake_path=mocker.Mock()
moe.config.config(假路径,lambda p:None)
fake_path.mkdir.assert_调用了_once_(parents=True)
向用于初始化数据库的函数\uuuuuuu init\uuuuuu添加一个附加参数。默认情况下,您将使用类本身提供的函数
def __init__(
self,
config_dir: pathlib.Path = pathlib.Path().home() / ".config" / "moe",
db_initializer=None
):
"""Read configuration.
Args:
config_dir: Path of the configuration directory.
"""
self.config_dir = config_dir
if not self.config_dir.exists():
self.config_dir.mkdir(parents=True)
self.db_path: pathlib.Path = self.config_dir / "library.db"
if db_initializer is None:
db_intializer = self._init_db
db_initializer(self.dp_path)
@staticmethod
def _init_db(p):
engine = sqlalchemy.create_engine("sqlite:///" + str(p))
library.Session.configure(bind=engine)
library.Base.metadata.create_all(engine)
def\uu init__(
自己
config_dir:pathlib.Path=pathlib.Path().home()/“.config”/“moe”,
db_初始值设定项=无
):
“”“读取配置。
Args:
config_dir:配置目录的路径。
"""
self.config\u dir=config\u dir
如果不是self.config_dir.exists():
self.config_dir.mkdir(parents=True)
self.db_path:pathlib.path=self.config_dir/“library.db”
如果db_初始值设定项为“无”:
db\u initializer=self.\u init\u db
db_初始值设定项(self.dp_路径)
@静力学方法
定义初始数据库(p):
engine=sqlalchemy.create_engine(“sqlite://“+str(p))
library.Session.configure(bind=engine)
library.Base.metadata.create_all(引擎)
当您测试该函数时,您将传递一个不执行任何操作的函数
def test_config_dir_dne(self, mocker):
"""We should create the config directory if it doesn't exist."""
fake_path = mocker.Mock()
moe.config.Config(fake_path, lambda p: None)
fake_path.mkdir.assert_called_once_with(parents=True)
def test\u config\u dir\u dne(自模拟):
“”“如果配置目录不存在,我们应该创建它。”“”
fake_path=mocker.Mock()
moe.config.config(假路径,lambda p:None)
fake_path.mkdir.assert_调用一次(parents=True)
什么是mocker
?假设您使用的是unittest.mock
,请改用MagicMock
,这样您的实例就可以支持必要的魔法方法,\uuuuuu truediv\uuuu
。对不起,我应该解释一下。它只是pytest mock
为unittest.mock
使用的名称空间。这确实修复了这个错误,但我认为问题仍然存在。什么是mocker
?假设您使用的是unittest.mock
,请改用MagicMock
,这样您的实例就可以支持必要的魔法方法,\uuuuuu truediv\uuuu
。对不起,我应该解释一下。它只是pytest mock
为unittest.mock
使用的名称空间。这确实纠正了这个错误,但我认为问题仍然存在。好吧,这是有道理的。有哪种方法比其他方法更有利#3听起来我将有一堆不必要的函数