【问题标题】:Can I fake/mock the type of my mock objects in python unittests我可以在 python 单元测试中伪造/模拟我的模拟对象的类型吗
【发布时间】:2012-07-02 04:50:53
【问题描述】:

在我的 python 代码中,我检查其中一个参数的类型以确保它是我期望的类型。例如:

def myfunction(dbConnection):
    if (type(dbConnection)<>bpgsql.Connection):
        r['error'] += ' invalid database connection'

我想传递一个模拟连接以进行测试。有没有办法让模拟对象伪装成正确的类型?

【问题讨论】:

  • 使用duck typing 而不是依赖确切的类名。
  • 所以基本上答案是否定的,你不能伪造你的类型,而是不要直接检查类型,看看它是否像鸭子一样走路,如果是那么它就足够了,对吧?
  • @Ali isinstance(x, Foo) 如果xFoo,则返回true,包括如果xFoo 的子类的实例。
  • 没错。你不应该直接比较类型。这不仅会阻止像这样的测试,而且如果相同的模块被导入两次导致相同类型的不同类定义比较不相等,则会导致问题。 也已弃用,请使用 !=.
  • @Martijn,它会出现在旧版本的 IDLE 中。这是我曾经真正发生过的事情。

标签: python unit-testing mocking


【解决方案1】:

恕我直言,看来你们不太对劲!

我可以使用鸭子打字,但有一种方法可以做我最初打算做的事情:

来自http://docs.python.org/dev/library/unittest.mock.html

使用类或实例作为specspec_set 的模拟对象能够通过isintance 测试:

>>>
>>> mock = Mock(spec=SomeClass)
>>> isinstance(mock, SomeClass)
True
>>> mock = Mock(spec_set=SomeClass())
>>> isinstance(mock, SomeClass)
True

所以我的示例代码如下:

m = mock.MagicMock(spec=bpgsql.Connection)
isinstance(m, bpgsql.Connection) 

返回真

话虽如此,我并不是在争论在 python 中进行严格的类型检查,我说如果你需要检查它你可以做到,它也适用于测试和模拟。

【讨论】:

  • 另外,有时您只是无法控制另一个库的工作方式。如果外部的东西正在检查类型,最简单的方法可能是使用规范或至少将模拟的__class__ 设置为正确的类型。
  • 我试过这个用于 PyCharm 的静态检查,但无济于事。似乎它应该可以工作;你可以在这里找到错误:youtrack.jetbrains.com/issue/PY-10477
【解决方案2】:

这或多或少正是您不应该强制执行严格类型检查的原因!您应该从代码中完全删除该行。

如果您不想这样做,请使用您想要的属性(.connect().cursor()、...?)编写一个抽象基类并检查其中的isinstance

另外,&lt;&gt; 已被 aaages 淘汰。使用!=

【讨论】:

猜你喜欢
  • 2018-12-27
  • 1970-01-01
  • 2022-09-30
  • 2010-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多