1. ホーム
  2. python

Python モック パッチ os.environ と戻り値

2023-11-01 01:46:06

質問

モックを使用したconn()のユニットテスト。

app.py

import mysql.connector
import os, urlparse


def conn():
    if "DATABASE_URL" in os.environ:
        url = urlparse(os.environ["DATABASE_URL"])
        g.db = mysql.connector.connect(
            user=url.username,
            password=url.password,
            host=url.hostname,
            database=url.path[1:],
        )
    else:
        return "Error"


test.py

def test_conn(self):
    with patch(app.mysql.connector) as mock_mysql:
        with patch(app.os.environ) as mock_environ:
            con()
            mock_mysql.connect.assert_callled_with("credentials")

エラーです。 アサーション mock_mysql.connect.assert_called_with は呼び出されません。

というのは、'Database_url' が私のパッチした os.environ になく、そのため mysql_mock.connect へのテスト呼び出しが行われないからだと思います。

質問です。

1 このテストコードを動作させるために、どのような変更が必要ですか?

2.私はまた、'urlparse'にパッチを適用する必要がありますか?

どのように解決するのですか?

あなたは、次のことを試すことができます。 unittest.mock.patch.dictを実行してみてください。 の解決策です。単に conn を使って dummy 引数で指定します。

import mysql.connector
import os, urlparse


@mock.patch.dict(os.environ, {"DATABASE_URL": "mytemp"}, clear=True)  # why need clear=True explained here https://stackoverflow.com/a/67477901/248616
def conn(mock_A):
    print os.environ["mytemp"]
    if "DATABASE_URL" in os.environ:
        url = urlparse(os.environ["DATABASE_URL"])
        g.db = mysql.connector.connect(
            user=url.username,
            password=url.password,
            host=url.hostname,
            database=url.path[1:],
        )
    else:
        return "Error"

また、元の関数を変更したくない場合は、この解決策を試してみてください。

def func():
    print os.environ["mytemp"]


def test_func():
    k = mock.patch.dict(os.environ, {"mytemp": "mytemp"})
    k.start()
    func()
    k.stop()


test_func()