在 py.test 中模拟标准库调用
mocking a standard library calls in py.test
我正在学习如何使用 py.test 编写测试,但我不知道如何模拟外部调用。
假设我有一个测试代码:
app.py:
import random
def trade_robot(stock, price):
return ' '.join((random.choice(('buy', 'sell', 'keep')), stock))
而且我想确保我检查 random.choice 决定我需要购买的大小写(并且我想检查它是否正确连接 'buy' 大小写的字符串)。
我的测试代码应该是这样的:
import pytest
from app import trade_robot
import sys
def test_buy_case():
# some mock magic here
assert trade_robot('AAPL', 500) == 'buy AAPL'
if __name__ == "__main__":
pytest.main("-v %s" % sys.argv[0])
'some mock magic' 中应该包含什么才能使此测试每次都通过?谢谢!
您可以使用 'patch' 装饰器模拟外部调用:
http://www.voidspace.org.uk/python/mock/patch.html
例如你可以用
来模拟 'random.choice'
@patch('random.choice')
def test_foo(choice):
choice.return_value = some value
关键是打补丁的地方:
http://www.voidspace.org.uk/python/mock/patch.html#id1
自 Python 3.3.
以来,可以使用库 mock
, which is included into standard library 来完成
首先,使用上下文管理器:
import random
with mock.patch.object(random, 'choice') as m:
m.return_value = 'buy'
print random.choice(['anything']) # prints 'buy' regardless of the arguments
与装饰器相同:
@mock.patch.object(random, 'choice')
def test_buy(m):
m.return_value = 'buy'
print random.choice(['anything'])
该库还允许对模拟调用进行断言,并且对于单元测试来说是不可替代的。或者,有些人更喜欢显式依赖倒置,这意味着将函数 random.choice
作为 function/method/constructor 参数传递到您的代码中,并在测试中用模拟替换它。
我正在学习如何使用 py.test 编写测试,但我不知道如何模拟外部调用。
假设我有一个测试代码:
app.py:
import random
def trade_robot(stock, price):
return ' '.join((random.choice(('buy', 'sell', 'keep')), stock))
而且我想确保我检查 random.choice 决定我需要购买的大小写(并且我想检查它是否正确连接 'buy' 大小写的字符串)。
我的测试代码应该是这样的:
import pytest
from app import trade_robot
import sys
def test_buy_case():
# some mock magic here
assert trade_robot('AAPL', 500) == 'buy AAPL'
if __name__ == "__main__":
pytest.main("-v %s" % sys.argv[0])
'some mock magic' 中应该包含什么才能使此测试每次都通过?谢谢!
您可以使用 'patch' 装饰器模拟外部调用:
http://www.voidspace.org.uk/python/mock/patch.html
例如你可以用
来模拟 'random.choice'@patch('random.choice')
def test_foo(choice):
choice.return_value = some value
关键是打补丁的地方: http://www.voidspace.org.uk/python/mock/patch.html#id1
自 Python 3.3.
以来,可以使用库mock
, which is included into standard library 来完成
首先,使用上下文管理器:
import random
with mock.patch.object(random, 'choice') as m:
m.return_value = 'buy'
print random.choice(['anything']) # prints 'buy' regardless of the arguments
与装饰器相同:
@mock.patch.object(random, 'choice')
def test_buy(m):
m.return_value = 'buy'
print random.choice(['anything'])
该库还允许对模拟调用进行断言,并且对于单元测试来说是不可替代的。或者,有些人更喜欢显式依赖倒置,这意味着将函数 random.choice
作为 function/method/constructor 参数传递到您的代码中,并在测试中用模拟替换它。