web-dev-qa-db-ja.com

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

モックを使用した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 mysql.connector.error.Errors as err:
     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」にもパッチを適用する必要がありますか?

29
immrsteel
import mysql.connector
import os,urlparse
@mock.patch.dict(os.environ,{'DATABASE_URL':'mytemp'})
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 mysql.connector.error.Errors as err:
     return "Error

この方法で試すことができます。conn引数を指定してdummyを呼び出すだけです。

または

Urの元の関数を変更したくない場合は、これを試してください:

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

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

test_func()
51
vks

このため、環境変数を設定する必要があるときに pytestのmonkeypatchフィクスチャ がより良いコードにつながることがわかりました。

def test_conn(monkeypatch):
    monkeypatch.setenv('DATABASE_URL', '<URL WITH CREDENTIAL PARAMETERS>')
    with patch(app.mysql.connector) as mock_mysql:
        conn()
    mock_mysql.connect.assert_callled_with(<CREDENTIAL PARAMETERS>)
10
Toote

この question で説明されているmodified_environコンテキストマネージャーのようなものを使用して、環境変数を設定/復元することもできます。

with modified_environ(DATABASE_URL='mytemp'):
    func()
3
Laurent LAPORTE