问题描述
我有一个负责选择回调方法的模块。
我想模拟方法choice
,但即使看起来它被模拟,它仍然返回随机结果(有时测试通过,有时失败)。
这种不确定行为的原因是什么?
decision.py
:
from numpy.random.mtrand import choice
class RandomDecision:
def __init__(self, f_bet, f_call, f_fold):
bet, call, fold = 0.15, 0.50, 0.35
self.propabilities = [bet, call, fold]
self.choices = [f_bet, f_call, f_fold]
def decide(self, player=None, information=None):
decision = choice(self.choices, 1, p=self.propabilities)[0]
args = ()
if decision == self.f_bet:
args = self._get_random_bet(information, player),
decision(*args)
# some more methods...
现在让我们试试吧
test_decisions.py
from unittest.mock import Mock, patch
from decision import RandomDecision
class TestRandomDecisions(unittest.TestCase):
def setUp(self):
self.fold = Mock()
self.call = Mock()
self.bet = Mock()
self.rand_decision = RandomDecision(f_fold=self.fold,
f_call=self.call,
f_bet=self.bet)
def test_call(self):
bet = 40
with patch('numpy.random.mtrand.choice', side_effect=[self.call]),\
patch('decision.RandomDecision._get_random_bet',
return_value=bet):
self.rand_decision.decide(Mock(), None)
self.assertTrue(self.call.called)
1楼
当我开始玩patch
时,我遇到了完全相同的问题。
问题在于,这种说法做得有点偷偷摸摸。
from numpy.random.mtrand import choice
它将choice
属性从numpy.random.mtrand
模块复制到decision
模块。
当您从decision
模块调用choice()
,您使用的是本地副本而不是原始副本。
您的测试是模拟原始的,并且您的代码使用其本地副本,因此它不使用模拟版本。
如果你将patch('numpy.random.mtrand.choice', side_effect=[self.call])
更改为patch('decision.choice', side_effect=[self.call])
,它应该可以工作。