如何在 Python 中模拟这个单元测试?
How to mock this unit test in Python?
这是我要测试的方法。在此测试方法 (test_get_all_products) 中,我想传入一个产品列表和一个由 dal 标识的数据库调用的模拟响应。
def get_all_user_standalone_products(all_products, dal):
standalone_products = []
if all_products is not None:
all_products = all_products['userRenewableProduct']
for product in all_products:
sku_id = product.get('skuID', 0)
sku_cost_id = product.get('skuCostID', 0)
standalone_product = which_standalone_product(sku_id)
if product.get('isDisabled') or standalone_product is None:
continue
product['productType'] = standalone_product['name']
sku_cost_data = dal.skucosts.get_costs_for_sku_cost_id(
sku_cost_id)
product['termMonths'] = sku_cost_data['termMonths']
upgrade_sku_ids = standalone_product.get(
'upgrade_sku_ids', [])
if len(upgrade_sku_ids) > 0:
product['canUpgrade'] = True
product['upgradeSkus'] = upgrade_sku_ids
standalone_products.append(product)
return standalone_products
这是我的测试
product_sku_cost= {
u'testPriceSetID':u'',
u'skuID':88,
u'currencyTypeID':1,
u'termMonths':1,
u'dateCreated': u'2015-10-07T17:03:00 Z',
u'skuCostID':2840,
u'cost':9900,
u'skuTypeID':13,
u'dateModified': u'2015-10-07T17:03:00 Z',
u'isDefault':True,
u'name':u'Product'}
@patch('model.dal')
def test_get_all_products(self, dal):
# this is my mock - I want it to return the dictionary above.
dal.SKUCosts.get_costs_for_sku_cost_id.return_value = product_sku_cost
products = get_all_user_standalone_products(renewable_products, dal)
assert products[0]['canUpgrade'] is True
assert products[0]['termMonths'] == 1
但是当我断言来自模拟对象的 products[0]['termMonths'] == 1 时,它失败了,因为 termMonths 实际上是 Mock 对象本身,而不是 return值(product_sku_cost)我在期待。
请帮我找出上面我做错了什么。
这只是一个打字错误:尝试将 SKUCost
更改为您配置 dal
的 skucost
。所以配置行变成:
dal.skucsts.get_costs_for_sku_cost_id.return_value = product_sku_cost
无论如何,您的测试中还有一些其他问题:您不需要在测试中修补任何内容,因为您正在传递 dal
对象并且没有使用 model.dal
引用。我不知道 model.dal
是什么,但如果你想做的是拥有相同的 signature/properties,你可以使用 create_autospec
来构建它。
您的测试可以是:
def test_get_all_products(self, dal):
# this is my mock - I want it to return the dictionary above.
dal = create_autospec(model.dal)
dal.skucosts.get_costs_for_sku_cost_id.return_value = product_sku_cost
...
如果 model.dal
是 class,则在创建 autospec 时使用 instance=True
。
这是我要测试的方法。在此测试方法 (test_get_all_products) 中,我想传入一个产品列表和一个由 dal 标识的数据库调用的模拟响应。
def get_all_user_standalone_products(all_products, dal):
standalone_products = []
if all_products is not None:
all_products = all_products['userRenewableProduct']
for product in all_products:
sku_id = product.get('skuID', 0)
sku_cost_id = product.get('skuCostID', 0)
standalone_product = which_standalone_product(sku_id)
if product.get('isDisabled') or standalone_product is None:
continue
product['productType'] = standalone_product['name']
sku_cost_data = dal.skucosts.get_costs_for_sku_cost_id(
sku_cost_id)
product['termMonths'] = sku_cost_data['termMonths']
upgrade_sku_ids = standalone_product.get(
'upgrade_sku_ids', [])
if len(upgrade_sku_ids) > 0:
product['canUpgrade'] = True
product['upgradeSkus'] = upgrade_sku_ids
standalone_products.append(product)
return standalone_products
这是我的测试
product_sku_cost= {
u'testPriceSetID':u'',
u'skuID':88,
u'currencyTypeID':1,
u'termMonths':1,
u'dateCreated': u'2015-10-07T17:03:00 Z',
u'skuCostID':2840,
u'cost':9900,
u'skuTypeID':13,
u'dateModified': u'2015-10-07T17:03:00 Z',
u'isDefault':True,
u'name':u'Product'}
@patch('model.dal')
def test_get_all_products(self, dal):
# this is my mock - I want it to return the dictionary above.
dal.SKUCosts.get_costs_for_sku_cost_id.return_value = product_sku_cost
products = get_all_user_standalone_products(renewable_products, dal)
assert products[0]['canUpgrade'] is True
assert products[0]['termMonths'] == 1
但是当我断言来自模拟对象的 products[0]['termMonths'] == 1 时,它失败了,因为 termMonths 实际上是 Mock 对象本身,而不是 return值(product_sku_cost)我在期待。
请帮我找出上面我做错了什么。
这只是一个打字错误:尝试将 SKUCost
更改为您配置 dal
的 skucost
。所以配置行变成:
dal.skucsts.get_costs_for_sku_cost_id.return_value = product_sku_cost
无论如何,您的测试中还有一些其他问题:您不需要在测试中修补任何内容,因为您正在传递 dal
对象并且没有使用 model.dal
引用。我不知道 model.dal
是什么,但如果你想做的是拥有相同的 signature/properties,你可以使用 create_autospec
来构建它。
您的测试可以是:
def test_get_all_products(self, dal):
# this is my mock - I want it to return the dictionary above.
dal = create_autospec(model.dal)
dal.skucosts.get_costs_for_sku_cost_id.return_value = product_sku_cost
...
如果 model.dal
是 class,则在创建 autospec 时使用 instance=True
。