【问题标题】:In Python, how do I write unit tests that can access private attributes without exposing them?在 Python 中,如何编写可以访问私有属性而不暴露它们的单元测试?
【发布时间】:2011-12-24 13:35:59
【问题描述】:

我正在尝试改进为 Python 程序编写单元测试用例的方式。我注意到在某些情况下,访问私有成员以确保方法正常运行会非常有帮助。一个示例情况是,尝试测试一个方法是否具有正确的行为,该方法除了 None 之外没有预期的返回值。我知道这样做的简单和错误的方法是将私有属性改为受保护的属性并直接测试它们。但是,我想找到一种不会过多暴露接口的方法。

那么,我如何在不将它们暴露在接口中的情况下测试类中的私有属性,或者,如果适用,如何更好地测试这种场景,以便正确的单元测试不一定需要私有属性访问?

【问题讨论】:

  • 什么是 Python 中的“私有”和“受保护”属性?没有这样的东西。
  • 这是一个敏感的话题;一些指导方针说,如果它是私有的,则不需要测试!
  • @Sven _var1__var2 分别是受保护的还是私有的呢?
  • 我同意@glowcoder,你的单元测试应该只测试你的对象的暴露功能。因此,如果某些东西是隐藏的,那么只有内部方法应该使用它。您(以及您的测试)需要了解(和测试)您的对象的所有内容 - 都是公共属性。
  • 有时能够测试类的内部方法很有用,因为从公共方法调用时,正确测试它们的所有路径都太复杂了。但这通常意味着您的课程需要拆分重构为多个较小的位,所以我会和其他人一起去:私有,不要测试。它应该包含在您对公共方法的测试中。

标签: python unit-testing testing tdd access-modifiers


【解决方案1】:

在 Python 中没有什么是私有的。如果您在成员变量上使用双下划线前缀,则名称只是被破坏了。您可以通过以_Class__member 形式限定名称来访问它。这将访问Class 类中的__member 变量。

另请参阅此问题:Why are Python's 'private' methods not actually private?

【讨论】:

  • 如果你不使用_Class__member,它们是私有的
  • @Gutzofter:这不是私人的,只是被破坏了。它绝不会阻止您访问该成员,它只需要您跳过一个箍来访问它。
【解决方案2】:

我要去一个不同的方向......

尝试编写单元测试来断言公共行为优于私有状态。假设您调用 void 方法 A() 来修改内部状态。现在,如果调用该方法并且状态确实发生了变化,那么在您的小代码世界中将会有一些可观察到的变化。也许 B() 现在的行为有所不同。所以我的测试将是......(简化示例)

void MyTest()
{
   Assert.That(B(), Is.False);
   A();
   Assert.That(B(), Is.True);
}

避免在测试和 SUT 之间使用Inappropriate Intimacy

【讨论】:

  • 谢谢,这更像是我希望得到的答案。不适当的亲密关系是否是反模式/代码的不同名称,称为对象狂欢?如果我试图从命令设计模式测试具体命令类的 execute() 方法,如果它依赖于其他方法调用来更改状态,我将如何测试这样的函数,尤其是超出范围的状态命令类?
  • @grg-n-sox :命令类作用于命令目标。因此,您可以创建一个命令对象,将目标作为 ctor 参数传递。调用 Execute 然后断言命令目标上的预期更改。或者,您可以通过在它们之间创建目标接口/角色来将目标与命令隔离。然后你传入一个模拟命令作为 ctor 参数 & 只需断言该命令正在接口上调用正确的方法。
  • 我不确定对于单元测试来说,不恰当的亲密关系在 100% 的时间里是一件好事。当您的测试嵌入复杂逻辑时,如果您希望它们成为单元测试,最好测试该逻辑的小组件。
猜你喜欢
  • 2016-03-05
  • 1970-01-01
  • 1970-01-01
  • 2017-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多