- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
假设我们有以下结构:
class A():
class __A():
def __to_be_mocked(self):
#something here
def __init__(self):
with A.lock:
if not A.instance:
A.instance = A.__A()
def __getattr__(self,name):
return getattr(self.instance,name)
现在我们要模拟函数__to_be_mocked
。我们如何模拟它作为mock.patch.object
接受的目标是package.module.ClassName
。我已经尝试了所有方法,例如
target = A.__A
target = A.___A
还有更多。
编辑:
我用
解决了它target=A._A__A and attribute as '_A__to_be_mocked`
现在的问题是 __to_be_mocked
在 __A
里面,所以它不应该是 ___A__to_be_mocked
吗。
是因为A
中的setattribute
还是A中的__init__
?
最佳答案
我在 python 中模拟了很多东西,在做了很多次之后我可以说:
__something
属性(又称 private 属性)_something
属性(又名protected 属性)如果您模拟私有(private)事物,您会混淆生产和测试代码。当您进行此类模拟时,总有一种方法可以通过修补或模拟公共(public)或 protected 内容来获得相同的行为。
为了更好地解释我所说的混淆生产代码和测试代码的意思,我可以使用您的示例:修补 A.__B.__to_be_mocked()
(我替换了 __A
内部类通过 __B
使其更清楚)你需要写一些像
patch('amodule.A._A__B._B__to_be_mocked')
现在,通过修补 __to_be_mocked
,您可以在测试中传播 A
、B
和 to_be_mocked
名称:即正是我所说的纠结代码。因此,如果您需要更改某个名称,您应该进入所有测试并更改您的补丁,并且没有任何重构工具可以建议您更改 _A__B._B
字符串。
现在,如果你是一个好人并且把你的测试搞得一清二楚,那么你可以只在几个点上出现这些名字,但如果它是一个单例,我敢打赌它会像蘑菇一样被发现。
我想指出 private 和 protected 与某些安全问题无关,它们只是让您的代码更清晰的一种方式。这一点在 Python 中非常清楚,您无需成为黑客即可更改私有(private)或 protected 属性:这些约定在这里只是为了帮助您阅读可以说 Oh great 的代码!我不需要了解它是什么......它只是肮脏的工作。恕我直言,python 中的私有(private)属性无法实现此目标(__
太长,看到它真的很困扰我)并且 protected 就足够了。
旁注:理解 python 私有(private)命名的小例子:
>>> class A():
... class __B():
... def __c(self):
... pass
...
>>> a = A()
>>> dir(a)
['_A__B', '__doc__', '__module__']
>>> dir(a._A__B)
['_B__c', '__doc__', '__module__']
回到你的案例:你的代码如何使用 __to_be_mocked()
方法?是否可以通过在 A
(而不是 A.__A
)类中修补/模拟其他东西来产生相同的效果?
最后,如果您正在模拟私有(private)方法来感知要测试的东西,那么您来错地方了:永远不要测试肮脏的工作,它应该/可能/可以在不改变您的测试的情况下改变。您需要的是测试代码行为,而不是代码的编写方式。
如果你需要测试、补丁或模拟 protected 东西,也许你的类隐藏了一些合作者:测试它并使用你的测试来重构你的代码,然后清理你的测试。
的确:我在我的测试中散布了这种废话,然后当我明白我可以做得更好时,我会努力将其删除。
关于python - 如何模拟单例类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35569348/
我最近购买了《C 编程语言》并尝试了 Ex 1-8这是代码 #include #include #include /* * */ int main() { int nl,nt,nb;
早上好!我有一个变量“var”,可能为 0。我检查该变量是否为空,如果不是,我将该变量保存在 php session 中,然后调用另一个页面。在这个新页面中,我检查我创建的 session 是否为空,
我正在努力完成 Learn Python the Hard Way ex.25,但我无法理解某些事情。这是脚本: def break_words(stuff): """this functio
我是一名优秀的程序员,十分优秀!