嘲笑雪花连接

She*_*man 5 pytest python-unittest python-unittest.mock snowflake-cloud-data-platform

我在 python 中有一个 SnowflakeApi 类,它只是作为 SnowflakeConnection 类之上的包装器。我的 SnowflakeApi 是

import logging
import os
from snowflake.connector import connect    

class SnowflakeApi(object):
    """
    Wrapper to handle snowflake connection
    """

    def __init__(self, account, warehouse, database, user, pwd):
        """
        Handles snowflake connection. Connection must be closed once it is no longer needed
        :param account:
        :param warehouse:
        :param database:
        """
        self.__acct = self._account_url(account)
        self.__wh = warehouse
        self.__db = database
        self.__connection = None
        self.__user = user
        self.__pwd = pwd

    def __create_connection(self):

        try:
            # set the proxy here
            conn = connect(
                account=self.__acct
                , user=self.__user
                , password=self.__pwd
                , warehouse=self.__wh
                , database=self.__db
            )
            return conn
        except:
            raise Exception(
                "Unable to connect to snowflake for user: '{0}', warehouse: '{1}', database: '{2}'".format(
                    self.__user, self.__wh, self.__db))


    def get_connection(self):
        """
        Gets a snowflake connection. If the connection has already been initialised it is returned
        otherwise a new connection is created
        :param credentials_func: method to get database credentials.
        :return:
        """
        try:
            if self.__connection is None:
                self.__connection = self.__create_connection()
            return self.__connection
        except:
            raise Exception("Unable to initalise Snowflake connection")

    def close_connection(self):
        """
        Closes snowflake connection.
        :return:
        """
        self.__connection.close()
Run Code Online (Sandbox Code Playgroud)

SnowflakeApi的命名空间是connection.snowflake_connection.SnowflakeApi(即我在名为connections的文件夹中有snowflake_connection.py)

我想使用 pytest 和 unittest.mock 为此类编写单元测试。问题是我想模拟“连接”,以便返回 MagicMock 对象并且不进行数据库调用。到目前为止我已经尝试过:

  1. Monkeypatch.setattr(connections.snowflake_connection,"连接",return_value = "")
  2. 将我原来的课程更改为仅导入雪花。然后我创建了一个模拟对象并使用monkeypatch.setattr(snowflake_connection,"snowflake",my_mock_snowflake)。那也没用

简而言之,我尝试了其他一些方法,但没有任何效果。我想做的只是模拟雪花连接,因此不会进行实际的数据库调用。

Hus*_*hra 6

snowflake connector, cursor and fetch_all这是我们模拟使用的另一种方式python mock and patch

import mock
import unittest
from datetime import datetime, timedelta

import feed_daily_report


class TestFeedDailyReport(unittest.TestCase):
    @mock.patch('snowflake.connector.connect')
    def test_compare_partner(self, mock_snowflake_connector):
        tod = datetime.now()
        delta = timedelta(days=8)
        date_8_days_ago = tod - delta
        query_result = [('partner_1', date_8_days_ago)]
        mock_con = mock_snowflake_connector.return_value
        mock_cur = mock_con.cursor.return_value
        mock_cur.fetchall.return_value = query_result
        result = feed_daily_report.main()
        assert result == True
Run Code Online (Sandbox Code Playgroud)


Wil*_*ing 3

unittest.mock使用和修补连接的示例:

from unittest import TestCase
from unittest.mock import patch
from connection.snowflake_connection import SnowflakeApi

class TestSnowFlakeApi(TestCase):

    @patch('connection.snowflake_connection.connect')
    def test_get_connection(self, mock_connect)
        api = SnowflakeApi('the_account', 
                           'the_warehouse', 
                           'the_database', 
                           'the_user', 
                           'the_pwd')

        api.get_connection()

        mock_connect.assert_called_once_with(account='account_url',  # Will be the output of self._account_url()
                                             user='the_user',
                                             password='the_pwd',
                                             warehouse='the_warehouse',
                                             database='the_database')
Run Code Online (Sandbox Code Playgroud)

如果您正在测试使用您的包装器的其他类SnowFlakeApi,那么您应该使用相同的方法,但SnowFlakeApi在这些测试中修补自身。

from package.module.SomeClassThatUsesSnowFlakeApi

class TestSomeClassThatUsesSnowFlakeApi(TestCase):

    @patch('package.module.SnowFlakeApi')
    def test_some_func(self, mock_api):
        instance = SomeClassThatUsesSnowFlakeApi()
        instance.do_something()

        mock_api.assert_called_once_with(...)
        mock_api.return_value.get_connection.assert_called_once_with()
Run Code Online (Sandbox Code Playgroud)

另请注意,如果您使用的是 Python 2,则需要pip install mock然后from mock import patch.