【发布时间】:2014-08-05 15:26:09
【问题描述】:
我有以下结构:
class A(Object):
def method(self):
return 'a'
class B(A):
def __init__(self, test):
self.test = test
def method(self):
if self.test:
return super(A, self).method(self)
else:
return 'b'
我想做的是编写一个测试用例,测试如果 self.test 为真,则调用超级函数并调用 A 类的方法函数。
我怎样才能做到这一点?我应该模拟什么?
进阶 Q:如果 A 类和 B 类在一个单独的模块中,并且它们具有相同的名称,该怎么办? 所以我会写而不是B类:A类(module1.A): 这会改变嘲笑吗?
【问题讨论】:
-
你不能给
A.method打补丁吗? ...with mock.patch.object(A, 'method'): ...你不应该关心它是如何被调用的(例如,通过 super 或其他方式......)重要的是它被调用的 。 -
您的测试应该只关心
method返回'a'或'b'。该方法如何实现这一点不是您的测试应该关心的。如果将来您想重构B.method()并且它不再使用super(),那么如果它的行为仍然相同,那么您的方法同样有效。 -
@MartijnPieters 如果您不模拟对外部类的调用,那不就是一种集成测试吗?我有一种感觉(来自 Sandi Metz 的谈话),你所说的只有在处理对私有方法的调用时才是正确的(不要模拟它们,只是断言最终的公共副作用或返回值)。但是,对内部公共方法的模拟调用确实会创建对实现的依赖,所以我不确定了。
-
@MartijnPieters 我刚刚再次查看了 Metz 的演讲,我认为我部分错了。在查询消息的情况下,我们只对方法最后返回的内容感兴趣(不管它在内部调用什么)。如果消息不是查询而是命令(它改变了某些状态),我们有兴趣断言实例上的公共副作用,或模拟对外部实例的调用。但我觉得我仍然缺少一些东西。我们是否应该模拟对内部公共方法的调用,因为我们将分别对它们进行单元测试?演讲链接:youtube.com/watch?v=URSWYvyc42M
-
@KurtBourbaki:在实际的日常工作中:您总是可以稍后决定是否需要将被测单元分解为更小的单元,如果这有助于增加信心或回归已找到您要测试的。测试是一种工具,而不是最终目标,它服务于软件开发速度。不要让它陷入困境!
标签: python unit-testing mocking