14

我是一名 C# 开发人员,正在研究一些 Python 的东西,所以我还不知道我在做什么。我读过你真的不需要使用 Python 进行依赖注入。有人告诉我,您可以在代码中实例化对象并让它们以您想要的方式运行,但是,您可以将这些对象上的方法指向我自己在测试中定义的存根——据说没有模拟。

这是真的?我已经尝试过,但无法让它正常工作。这实际上是如何完成的?如何在没有模拟库的情况下在 Python 中存根方法?

4

2 回答 2

35

这是一个基本的例子。请注意,从不调用生产 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()
于 2010-10-11T22:47:00.290 回答
3

Python 函数是一等对象,因此您可以将任何函数分配给标识符:

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,因为有很多陷阱,例如管理存根范围等。

于 2020-07-03T18:23:03.523 回答