如何在不使用 Mock 的情况下对 Python 方法进行存根

问题描述 投票:0回答:3

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

这是真的吗? 我尝试过这样做,但无法完全发挥作用。 这实际上是如何完成的? 如何在没有模拟库的情况下对 Python 中的方法进行存根?

python unit-testing mocking stub
3个回答
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()

4
投票

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


0
投票

您可能想查看 mimicker — 针对此类场景设计的 HTTP 存根服务器。

它有一个干净且富有表现力的sdk

from mimicker import mimicker

mock_server = mimicker(8080).routes(
    get("/example").body({"message": "Hello"}).status(200)
)

with mock_server:
    # Run your REST client test code here.

另一个大优点 - 它是用 Python 的标准库构建的,因此不需要额外的膨胀或框架,如:flask、fast-api 等。

© www.soinside.com 2019 - 2024. All rights reserved.