如何在没有Mock的情况下存根Python方法

时间:2010-10-11 21:02:43

标签: python unit-testing mocking stub

我是一个C#dev进入一些Python的东西,所以我不知道我现在在做什么。我已经读过你不需要使用Python的依赖注入。我被告知你可以在你的代码中实例化对象并让它们以你想要的方式运行,但是,你可以将这些对象上的方法指向我自己的测试中定义的存根 - 假设没有模拟。

这是真的吗?我试过这样做,并不能让它工作。这实际上是怎么做到的?如何在没有模拟库的情况下在Python中存根方法?

2 个答案:

答案 0 :(得分:28)

这是一个基本的例子。请注意,永远不会调用生产getData()方法。它已经被存根嘲笑了。

import unittest
class ClassIWantToTest(object):

    def getData(self):
        print "PRODUCTION getData called"
        return "Production code that gets data from server or data file"

    def getDataLength(self):
        return len(self.getData())

class TestClassIWantToTest(unittest.TestCase):

    def testGetDataLength(self):
        def mockGetData(self):
            print "MOCK getData called"
            return "1234"

        origGetData = ClassIWantToTest.getData
        try:
            ClassIWantToTest.getData = mockGetData
            myObj = ClassIWantToTest()
            self.assertEqual(4, myObj.getDataLength())
        finally:
            ClassIWantToTest.getData = origGetData

if __name__ == "__main__":
    unittest.main()

答案 1 :(得分:0)

Python函数是first-class objects,因此您可以将任何函数分配给标识符:

class Person:
  def greetings(self):
    return "Hi!"

def happy_greetings(self):
  return "Hi! You're awesome!"

mike = Person()
mike.greetings()  # "Hi!"

Person.greetings = happy_greetings
mike.greetings()  # "Hi! You're awesome!"

认为方法标识符是对某些功能的引用。通过更改引用,Python解释器将查找并执行其引用的内容。但是,建议您不要使用手工完成的模块,而建议您使用一些成熟的模块,例如unittest.mock,因为存在很多陷阱,例如管理存根范围等。