Python mock Patch os.environ and return value

2020-02-05 00:56发布

Unit testing conn() using mock:

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")

Error: Assertion mock_mysql.connect.assert_called_with is not called.

which i believe it is because 'Database_url' is not in my patched os.environ and because of that test call is not made to mysql_mock.connect.

Questions:

1 what changes i need to make to make this test code work?

2.Do i also have to patch 'urlparse'?

3条回答
再贱就再见
2楼-- · 2020-02-05 01:37

You can also use something like the modified_environ context manager describe in this question to set/restore the environment variables.

with modified_environ(DATABASE_URL='mytemp'):
    func()
查看更多
对你真心纯属浪费
3楼-- · 2020-02-05 01:40

For this, I find that pytest's monkeypatch fixture leads to better code when you need to set environment variables:

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>)
查看更多
虎瘦雄心在
4楼-- · 2020-02-05 01:45
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

You can try this way.Just call conn with a dummy argument.

Or

If you dont want to modify ur original function try this:

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

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

test_func()
查看更多
登录 后发表回答