Python 模拟补丁 os.environ 和返回值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31582750/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 10:15:30  来源:igfitidea点击:

Python mock Patch os.environ and return value

pythonunit-testingpython-3.xdependency-injectionmocking

提问by immrsteel

Unit testing conn() using mock:

使用模拟单元测试 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")

Error: Assertionmock_mysql.connect.assert_called_withis not called.

错误:未调用断言mock_mysql.connect.assert_called_with

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.

我相信这是因为“Database_url”不在我修补的 os.environ 中,并且因为没有对 mysql_mock.connect 进行测试调用。

Questions:

问题:

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

1 我需要做哪些更改才能使此测试代码正常工作?

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

2.我还必须修补'urlparse'吗?

采纳答案by vks

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 connwith a dummyargument.

您可以尝试这种方式。只需conndummy参数调用即可。

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

回答by Laurent LAPORTE

You can also use something like the modified_environcontext manager describe in this questionto set/restore the environment variables.

您还可以使用类似modified_environ问题中描述的上下文管理器来设置/恢复环境变量。

with modified_environ(DATABASE_URL='mytemp'):
    func()

回答by Toote

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

为此,我发现当您需要设置环境变量时,pytest 的monkeypatch fixture会产生更好的代码:

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_called_with(<CREDENTIAL PARAMETERS>)