如何在Python中模拟一个类?

2 投票
2 回答
2186 浏览
提问于 2025-04-16 15:30

我刚开始学Python,不过之前用过Ruby。

我想用Python做一些测试,但我不知道怎么为我的测试模拟一个类。

假设我有这样一个真实的类:

from database import DB
class Foo:
  def do_it(self):
    x = {'key': 'value'}
    DB.save(x)
    # do other stuff with x
    return x

现在,我想测试我对x做的所有操作是否都能得到正确的结果,而且我想检查DB.save这个方法是否用x作为参数被调用,但我不想真的把x保存到数据库里。为了查看DB.save是否被调用,我可以使用一些模拟框架,但我该怎么告诉Foo类让我用模拟对象而不是实际的DB对象呢?

谢谢你。

补充:抱歉,我的例子没有足够清楚,无法满足我的需求。

我们来看这个新例子:

from database import DB
class Foo:
  DB.connect()
  def do_it(self):
    x = {'key': 'value'}
    DB.save(x)
    # do other stuff with x
    return x

比如说,假设数据库出现故障。

当我导入Foo时,它会抛出连接错误,而我没有时间去模拟DB。

我该怎么办呢??

2 个回答

6

每次调用 Foo.do_it() 时,DB 都会在模块的范围内被查找。你可以简单地给 DB 赋值一个不同的对象,这样它就会使用这个新的对象。如果你的类 Foo 在某个模块 foo 中,你可以这样做:

import foo
foo.DB = mocked_DB
f = foo.Foo()
f.do_it()
7

答案是,不要这样写你的类。这种写法其实很奇怪——在类的层面上,除了定义属性和方法之外,应该没有可执行的代码。你应该在 __init__ 方法里设置连接。

class Foo(object):
    def __init__(self, *args, **kwargs):
        DB.connect()

撰写回答