单元测试模拟 GCS

2024-03-09

我很难找到一种方法来进行单元测试read and write此类中存在的方法。我正在尝试使用模拟补丁库创建一个模拟,以避免调用 Google Storage,但我很难弄清楚如何做到这一点。

from google.cloud import storage


class GCSObject(str):
    

    def __init__(self, uri=""):
        self.base, self.bucket, self.path = self.parse_uri(uri)


    def parse_uri(self, uri):
        uri = uri.lstrip("gs://").replace("//", "/").split("/", 1)
        if len(uri) > 1:
            return ("gs://", uri[0], uri[1])
        else:
            return ("gs://", uri[0], "")

    def read(self) -> bytes:
        storage_client = storage.Client()
        bucket = storage_client.bucket(self.bucket)
        return bucket.blob(self.path).download_as_string()

    def write(self, content: bytes):
        storage_client = storage.Client()
        bucket = storage_client.get_bucket(self.bucket)
        blob = bucket.blob(self.path)
        blob.upload_from_string(content)

我目前正在尝试做的事情

@mock.patch("packages.pyGCP.pyGCP.gcs.storage.Client")
def test_upload(client):
    gcs_path = GCSObject("fake_path")
    reader = gcs_path.read()  
    #  confused what I should assert 

我在用google-cloud-storage==1.32.0和Python 3.7.5。这是单元测试解决方案:

gcs.py:

from google.cloud import storage


class GCSObject(str):

    def __init__(self, uri=""):
        self.base, self.bucket, self.path = self.parse_uri(uri)

    def parse_uri(self, uri):
        uri = uri.lstrip("gs://").replace("//", "/").split("/", 1)
        if len(uri) > 1:
            return ("gs://", uri[0], uri[1])
        else:
            return ("gs://", uri[0], "")

    def read(self) -> bytes:
        storage_client = storage.Client()
        bucket = storage_client.bucket(self.bucket)
        return bucket.blob(self.path).download_as_string()

    def write(self, content: bytes):
        storage_client = storage.Client()
        bucket = storage_client.get_bucket(self.bucket)
        blob = bucket.blob(self.path)
        blob.upload_from_string(content)

test_gcs.py:

import unittest
from unittest import mock
from unittest.mock import Mock
from gcs import GCSObject


class TestGCSObject(unittest.TestCase):
    @mock.patch('gcs.storage')
    def test_read(self, mock_storage):
        mock_gcs_client = mock_storage.Client.return_value
        mock_bucket = Mock()
        mock_bucket.blob.return_value.download_as_string.return_value = "teresa teng".encode('utf-8')
        mock_gcs_client.bucket.return_value = mock_bucket
        gcs = GCSObject('fake_path')
        actual = gcs.read()
        mock_storage.Client.assert_called_once()
        mock_gcs_client.bucket.assert_called_once_with('fake_path')
        mock_bucket.blob.assert_called_once_with('')
        mock_bucket.blob.return_value.download_as_string.assert_called_once()
        self.assertEqual(actual, "teresa teng".encode('utf-8'))

    @mock.patch('gcs.storage')
    def test_write(self, mock_storage):
        mock_gcs_client = mock_storage.Client.return_value
        mock_bucket = Mock()
        mock_gcs_client.get_bucket.return_value = mock_bucket
        gcs = GCSObject('fake_path')
        gcs.write(b'teresa teng')
        mock_storage.Client.assert_called_once()
        mock_gcs_client.get_bucket.assert_called_once_with('fake_path')
        mock_bucket.blob.assert_called_once_with('')
        mock_bucket.blob.return_value.upload_from_string.assert_called_once_with(b'teresa teng')


if __name__ == '__main__':
    unittest.main()

单元测试结果:

..
----------------------------------------------------------------------
Ran 2 tests in 0.004s

OK
Name                                     Stmts   Miss  Cover   Missing
----------------------------------------------------------------------
src/stackoverflow/64672497/gcs.py           18      1    94%   12
src/stackoverflow/64672497/test_gcs.py      29      0   100%
----------------------------------------------------------------------
TOTAL                                       47      1    98%
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

单元测试模拟 GCS 的相关文章

  • 为什么 dataclasses.astuple 返回类属性的深层副本?

    在下面的代码中astuple函数正在执行数据类的类属性的深层复制 为什么它不能产生与函数相同的结果my tuple import copy import dataclasses dataclasses dataclass class Dem
  • VSCode Settings.json 丢失

    我正在遵循教程 并尝试将 vscode 指向我为 Scrapy 设置的虚拟工作区 但是当我在 VSCode 中打开设置时 工作区设置 选项卡不在 用户设置 选项卡旁边 我还尝试通过以下方式手动转到文件 APPDATA Code User s
  • 使用主题交换运行多个 Celery 任务

    我正在用 Celery 替换一些自制代码 但很难复制当前的行为 我期望的行为如下 创建新用户时 应向tasks与交换user created路由键 该消息应该触发两个 Celery 任务 即send user activate email
  • python multiprocessing 设置生成进程等待

    是否可以生成一些进程并将生成进程设置为等待生成的进程完成 下面是我用过的一个例子 import multiprocessing import time import sys def daemon p multiprocessing curr
  • 矩形函数的数值傅里叶变换

    本文的目的是通过一个众所周知的分析傅里叶变换示例来正确理解 Python 或 Matlab 上的数值傅里叶变换 为此 我选择矩形函数 这里报告了它的解析表达式及其傅立叶变换https en wikipedia org wiki Rectan
  • GUI(输入和输出矩阵)?

    我需要创建一个 GUI 将数据输入到矩阵或表格中并读取此表单数据 完美的解决方案是限制输入表单仅允许float 例如 A 1 02 0 25 0 30 0 515 0 41 1 13 0 15 1 555 0 25 0 14 1 21 2
  • 打印包含字符串和其他 2 个变量的变量

    var a 8 var b 3 var c hello my name is var a and var b bye print var c 当我运行程序时 var c 会像这样打印出来 hello my name is 8 and 3 b
  • 为什么一旦我离开内置的运行服务器,Django 就无法找到我的管理媒体文件?

    当我使用内置的简单服务器时 一切正常 管理界面很漂亮 python manage py runserver 但是 当我尝试使用 wsgi 服务器为我的应用程序提供服务时django core handlers wsgi WSGIHandle
  • 使用 Python Oauthlib 通过服务帐户验证 Google API

    我不想使用适用于 Python 的 Google API 客户端库 但仍想使用 Python 访问 Google APIOauthlib https github com idan oauthlib 创建服务帐户后谷歌开发者控制台 http
  • pandas - 包含时间序列数据的堆积条形图

    我正在尝试使用时间序列数据在 pandas 中创建堆积条形图 DATE TYPE VOL 0 2010 01 01 Heavy 932 612903 1 2010 01 01 Light 370 612903 2 2010 01 01 Me
  • Pandas 组合不同索引的数据帧

    我有两个数据框df 1 and df 2具有不同的索引和列 但是 有一些索引和列重叠 我创建了一个数据框df索引和列的并集 因此不存在重复的索引或列 我想填写数据框df通过以下方式 for x in df index for y in df
  • 将 Matlab 的 datenum 格式转换为 Python

    我刚刚开始从 Matlab 迁移到 Python 2 7 在读取 mat 文件时遇到一些问题 时间信息以 Matlab 的日期数字格式存储 对于那些不熟悉它的人 日期序列号将日历日期表示为自固定基准日期以来已经过去的天数 在 MATLAB
  • 如何使用 Python 3 检查目录是否包含文件

    我到处寻找这个答案但找不到 我正在尝试编写一个脚本来搜索特定的子文件夹 然后检查它是否包含任何文件 如果包含 则写出该文件夹的路径 我已经弄清楚了子文件夹搜索部分 但检查文件却难倒了我 我发现了有关如何检查文件夹是否为空的多个建议 并且我尝
  • 我可以使用 moq Mock 来模拟类而不是接口吗?

    正在经历https github com Moq moq4 wiki Quickstart https github com Moq moq4 wiki Quickstart 我看到它 Mock 一个接口 我的遗留代码中有一个没有接口的类
  • Protobuf 如何编码 oneof 消息结构

    对于这个 python 程序 在编码时运行 protobuf 编码会给出以下输出 0a 10 08 7f8a 0104 08 02 10 0392 0104 08 02 10 03 18 01 我不明白的是为什么8a后面有一个01 为什么9
  • Spider 必须返回 Request、BaseItem、dict 或 None,已“设置”

    我正在尝试从以下位置下载所有产品的图像 我的蜘蛛看起来像 from shopclues items import ImgData import scrapy class multipleImages scrapy Spider name m
  • 为什么 csv.DictReader 给我一个无属性错误?

    我的 CSV 文件是 200 Service 我放入解释器的代码是 snav csv DictReader open screennavigation csv delimiter print snav fieldnames 200 for
  • 制作一份 Python 文档的 PDF 文件

    Python 官方网站提供 PDF 文档下载 但它们是按章节分隔的 我下载了源代码并构建了 PDF 文档 这些文档也是单独的 PDF 我怎么能够从源代码中的 Makefile 构建一个 PDF 文件 我认为这样阅读起来会更方便 如果连接单独
  • 如何在 Flask 中的视图函数/会话之间传递复杂对象

    我正在编写一个 Web 应用程序 当 且仅当 用户登录时 该应用程序从第三方服务器接收大量数据 这些数据被解析为自定义对象并存储在list 现在 用户在应用程序中使用这些数据 调用不同的视图 例如发送不同的请求 我不确定什么是最好的模式在视
  • pytest找不到模块[重复]

    这个问题在这里已经有答案了 我正在关注pytest 良好实践 https docs pytest org en latest explanation goodpractices html test discovery或者至少我认为我是 但是

随机推荐

  • 我的 iPhone 应用程序使用了多少内存(来自模拟器)

    我知道这与 Instruments 有关 但这有点令人困惑 并且在 Google 上搜索 Instruments 并没有多大帮助 我想知道我的应用程序运行情况如何 例如它使用了多少内存 我只是不知道在哪里可以找到类似的东西 据我们从模拟器中
  • Postgres COPY TO NULL 整数

    我有一个包含各种列的 CSV 其中一列包含整数数据 但是 当运行副本时 COPY soc FROM soc asc WITH DELIMITER 我得到以下信息 ERROR invalid input syntax for integer
  • ANTLR4 将 ParserRuleContext 树展平为数组

    如何压平一个ParserRuleContext将子树放入令牌数组中 这ParserRuleContext getTokens int ttype 看起来不错 但什么是ttype 是token类型吗 如果我想包含所有令牌类型 应使用什么值 P
  • 如何在 C# 中从两个列表创建单个对象对列表?

    我有两个对象列表 列表 A 和列表 B 我需要创建列表 C 将列表 A 和列表 B 组合成对 例如 List A object a1 object a2 object a3 List B object b1 object b2 object
  • 在命令行中在Kafka中创建多个消费者

    我是卡夫卡的新手 当我在命令行中运行快速启动示例时 我发现无法在命令行中创建多个使用者 健康 状况 我构建了一个名为 test 的主题 包含 3 个分区 并且还针对该主题构建了一个生产者 然后我想创建两个不同的消费者 共享关于此主题的名为
  • 格式化输出字符串,右对齐

    我正在处理包含坐标 x y z 的文本文件 1 128 1298039 123388 0 2 每行被分隔为 3 个项目 使用 words line split 处理数据后 我需要将坐标写回到另一个 txt 文件中 以便每列中的项目右对齐 以
  • Vimeo 视频链接正则表达式

    有人得到了 vimeo 视频链接的正则表达式 可以从段落中提取它们以在 php 中使用吗 似乎无法找到适合最新 vimeo url 方案的合适方案 Vimeo 有 4 个不同的公共视频链接 视频IDvimeo com Video ID 渠道
  • GRPC - .IllegalArgumentException:Jetty ALPN/NPN 尚未正确配置

    我正在尝试在 pod 上的 docker 容器中启用 TLS 来启动 GRPC 服务器 但在服务器启动期间出现以下错误 我正在尝试参考https github com grpc grpc java blob master SECURITY
  • numpy沿任意轴广播加法

    我想通过简单地沿一个或多个轴执行相同的加法来添加两个不同维度的数组 非矢量化解决方案 x np array 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 shape 4 3 2 y np a
  • 为什么 http 服务返回 observables 而不是 Promise

    我对导致角度 2 的推理或讨论感到好奇http服务返回可观察的结果而不是响应的承诺 我会理解 Web 套接字连接或长轮询请求之类的逻辑 但是http服务只是创建一个XMLHttpRequest 并且在load请求的事件处理程序 在响应可观察
  • 在 PL/SQL 中创建或模拟二维数组

    您能帮助我如何在 PL SQL 中为存储过程创建二维数组吗 这些列是动态的 因此它的类型也可以增长和变化 任何帮助表示赞赏 先感谢您 我有以下代码 Type CAR TABLE ARRAY is varray 2 of varchar2 2
  • 更改 UITabBarItem 图像

    我已经使用 Storyboard 来设置我的UITabBarController及其对应的ViewControllers 每当取消选择选项卡时 它都是灰色的 选择它时 它会呈现绿色 我想要其中之一UITabBarItems始终看起来相同 即
  • Font-Face 使用绝对路径

    是否可以使用绝对路径 fontace 我有以下目录结构 HP font Monoton woff Monoton eot css font css fontface css html index html 定义字体 font face fo
  • 在 C++11 中使用零或 NULL 哪个更好?

    如今 有了C 11 推荐使用什么 Zero or NULL 第一个还是第二个如果 int p getPointer if 0 p something if NULL p something UPDATE 我忘记新的了 if nullptr
  • Entity Framework Core - 版本 5+ 与输出数据库无关

    我有一个使用 EF Core 的应用程序 最初是使用 V3 1 1 编写的 我们决定冒险更新到 v5 0 1 现在它已经不再预览了 该应用程序支持 MSSQL 和 SQLite 最初运行得很好 迁移的创建基本上与工具和文档无关here ht
  • 您的启动项目“项目”未引用 Microsoft.EntityFrameworkCore.Design

    我正在使用 EntityFrameworkCore 版本 2 2 2 构建 WPF 应用程序 然而 当我想要Add Migration它向我输出一个错误 Your startup project project doesn t refere
  • 如何配置星号即时消息

    星号支持即时消息吗 我尝试为 IM 配置星号 从这个例子 https groups google com forum msg csipsimple users stBJYGQ88fw OgLW8CLVvIkJ 但是当我尝试将 IM 发送到另
  • 下限 > 0 的 .Net 数组

    虽然这可能是一件奇怪的事情 但我需要在 Net 中创建一个下限 gt 0 的数组 乍一看 这似乎是可能的 使用 Array CreateInstance typeof Object new int 2 new int 9 产生所需的结果 下
  • 一个maven项目如何依赖另一个本地maven项目?

    我有两个 Maven 项目project foo pom xml and project bar pom xml 我有foo取决于bar and I want that every timefoo pom xmlcompiles it ll
  • 单元测试模拟 GCS

    我很难找到一种方法来进行单元测试read and write此类中存在的方法 我正在尝试使用模拟补丁库创建一个模拟 以避免调用 Google Storage 但我很难弄清楚如何做到这一点 from google cloud import s