我正在尝试模拟另一个对象中包含的对象的实例方法。
我有两个对象
class CreditCard(object):
def charge(self, amount):
if amount < 0:
raise Exception('Invalid amount')
print "charging %d" % amount
class Transaction(object):
def __init__(self, credit_card, amount):
self.amount = amount
self.credit_card = credit_card
self.status = 'PRISTINE'
def pay(self):
self.credit_card.charge(self.amount)
self.status = 'COMPLETE'
这是我正在尝试实现的简化示例
class TestTransaction(TestCase):
def setUp(self):
cc = CreditCard()
t = Transaction(cc, 10)
def test_should_not_mark_transaction_as_complete_if_charge_failed(self):
with mock.patch('t.credit_card.charge') as mock_charge:
mock_charge.side_effect = Exception
with self.assertRaises(Exception):
t.pay()
self.assertEquaL(t.status, 'PRISTINE')
charge
内部有很多逻辑,所以我试图通过模拟收费来隔离交易测试。
谢谢,python 2.7
答案 0 :(得分:1)
由于您正在模拟类的方法,因此可以直接对其进行修补:
import mock
import unittest
from your_code import CreditCard, Transaction
class TestTransaction(unittest.TestCase):
def setUp(self):
self.cc = CreditCard()
self.t = Transaction(self.cc, 10)
@mock.patch('your_code.CreditCard.charge', side_effect=Exception)
def test_should_not_mark_transaction_as_complete_if_charge_failed(self, mock_charge):
with self.assertRaises(Exception):
self.t.pay()
self.assertEqual(self.t.status, 'PRISTINE')
请务必修改补丁中的模块路径,在哪里定义您的类。
此外,由于多个错误(在测试用例中使用全局变量而不是实例属性),我更正了您的初始示例。
答案 1 :(得分:0)
由于您要将CreditCard
个实例传递到Transaction
,只需创建一个Mock object并传递它。
class TestTransaction(TestCase):
def setUp(self):
self.fake_cc = Mock()
# set up any side effects, return values etc. of the fake cc
# in your tests as needed...
self.t = Transaction(self.fake_cc, 10)
def test_should_not_mark_transaction_as_complete_if_charge_failed(self):
self.fake_cc.side_effect = Exception
with self.assertRaises(Exception):
self.t.pay()