python - 在 unittest 中模拟库(在 Python 3.7 中)
问题描述
我有一个使用elasticsearch的类,我正在尝试为它编写单元测试。
from elasticsearch import Elasticsearch
class MyClass:
def __init__(self):
# ...
self.client = Elasticsearch(connection) # Connect to ES
def get_mapping(self):
mapping = self.client.indices.get_mapping(
index=self.index_name
)
# ... extra code that simplifies mapping
return mapping
这是我在单元测试中的内容:
from myproject.module.submodule import MyClass
class MyTestCase(unittest.TestCase): # pragma: no cover, duplicates expected
def setUp(self):
patcher = mock.patch('elasticsearch.Elasticsearch')
self.mock_es = patcher.start()
self.addCleanup(patcher.stop)
def test_mapping(self):
self.mock_es.indices.get_mapping.return_value = {
"some_index": {
"mappings": {
"properties": {
"field_one": {
"type": "text",
},
"field_two": {
"type": "text",
}
}
}
}
}
mapping = MyClass().get_mapping()
expected_mapping = {
"some_index": {
"field_one": "text",
"field_two": "text",
}
}
self.assertEqual(mapping, expected_mapping)
我的期望是,在运行单元测试时,永远不应该使用实际的库。 elasticsearch
但是,当我运行上面的代码时,它会尝试连接到 elasticsearch。
我究竟做错了什么?
解决方案
我想到了。有两个改变是必要的:
在 setUp() 中
elasticsearch.Elasticsearch
,我需要修补而不是修补myproject.module.submodule.Elasticsearch
。评论中提到了这一点。
而不是
self.mock_es.indices.get_mapping.return_value = <some_value>
应该是:instance = self.mock_es.return_value instance.indices.get_mapping.return_value = <some_value>
在模拟一个类之后,为了能够模拟一个方法的返回值,每个实例都需要被模拟,而不是类方法。
所以最终的测试类是:
class MyTestCase(unittest.TestCase): # pragma: no cover, duplicates expected
def setUp(self):
patcher = mock.patch('myproject.module.submodule.Elasticsearch')
self.mock_es = patcher.start()
self.addCleanup(patcher.stop)
def test_mapping(self):
instance = self.mock_es.return_value
instance.indices.get_mapping.return_value = {
"some_index": {
"mappings": {
"properties": {
"field_one": {
"type": "text",
},
"field_two": {
"type": "text",
}
}
}
}
}
mapping = MyClass().get_mapping()
expected_mapping = {
"some_index": {
"field_one": "text",
"field_two": "text",
}
}
self.assertEqual(mapping, expected_mapping)
推荐阅读
- typescript - 如何在 TypeScript 中访问 keyof 动态键?
- java - 在使用“日期”数据类型创建属性时,使用 Postgres 在 Hibernate 和 JPA 中出现问题
- typescript - Typescript 在 MacOS 上被错误识别为 MPEG 文件
- laravel - Laravel 返回带条件的关系数据
- javascript - 如何获得平均星级值(原生 mongodb & express)
- sql - 算术溢出错误将 nvarchar 转换为数据类型 numeric 以防万一查询
- java - 为什么反转一个 ArrayList 变量也会反转另一个?
- sql - SQL-在 1 列中获取具有多个值的值
- c - 如何直接打印最后一个错误代码,C中的文本
- python - 如何从 selenium 中的元素中删除属性