如何在Python中模拟类中的属性

时间:2016-05-04 05:32:56

标签: python unit-testing mocking pytest

这是我的第一个名为user.py的文件

from account import Account    
class User:
   def __init__(self, id):
       self.id = id
       self._account = None

   @property
   def account(self):
       if not self._account:
          self._account = Account(self.id)

       return self._account

   @property
   def has_discount(self)
       return self.account.discount_id > 0

我有第二个名为account.py的文件

class Account:
    def __init__(self, user_id):
        # some process to load DB data
        self.account = load_account(user_id)
        # do something after this to initialize account properties like discount, etc

    @property
    def discount_id(self):
       return self.discount_id

我的目标是测试user.py.我想做的一件事就是在user.py中为'has_discount'属性装饰器模拟Account对象。我想测试不同的场景,其中has_discount将返回0或任何其他数字。

如何使用补丁,我可以在User类中模拟Account对象以返回自定义值,以便我可以尝试不同的测试?

1 个答案:

答案 0 :(得分:0)

因为user模块导入Account到其自己的名称空间patching必须在那里而不是account模块。换句话说,您必须暂时更改Account模块中名称user所指的内容:

from user import User
from unittest.mock import patch

with patch('user.Account') as MockAccount:
    MockAccount.return_value.discount_id = 1
    u = User(1)                             
    print(u.has_discount)
    # True

with patch('user.Account') as MockAccount:
    MockAccount.return_value.discount_id = 0
    u = User(1)
    print(u.has_discount)
    # False
  

我想测试不同的场景,其中has_discount将返回0或任何其他数字。

在当前的实施中,User.has_discount将始终返回TrueFalse。您的意思是Account.discount_id吗?