具有自动指定依赖项的对象的类型提示

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

我正在为一些显然具有依赖性的控制器对象创建测试。我想测试它是否与依赖项正确交互,而无需出于明显的原因(数据库连接)实例化它们。所以我有一个类似的课程

class A:
  def __init__(self, some_dependency: InterfaceB):
    self.some_dependency: InterfaceB = some_dependency

  def do_thing(self, x):
    self.some_dependecy.do_subtask(necessary_data=x)

我想测试它是否正确地将值传递给它的依赖项,所以我做了这样的事情

def test_do_thing():
  a: A = A(some_dependency=create_autospec(InterfaceB))
  a.do_thing(1)
  assert a.some_dependency.do_subtask.called_with(necessary_data=1)

但是代码完成/linter 会抱怨 do_subtask 是一个函数并且没有 Called_with 属性,所以我必须这样做

do_subtask: Mock = cast(Mock, a.some_dependency.do_subtask)
assert do_subtask.called_with(necessary_data=1)

如果你想象一个具有多个依赖项的控制器,或者甚至只是使用一个依赖项的多种方法,它会变得非常乏味,而且不是很干,而且实际上非常湿(什么?可怕极了)。是否有任何解决方案可以按优先顺序执行以下任一操作

  1. 神奇地暗示 A 是 A 类型,但它的所有依赖项都是自动指定的,因此它们是它们的类型,但它们的方法将是模拟的?
  2. 类型提示表明变量是类型的自动规范,因此它具有该类型的所有方法,但它们实际上是 Mock 对象?
  3. 只是一种较少重复的方式来向 pycharm linter 声明它们是模拟的
python pycharm mocking type-hinting linter
1个回答
-1
投票

不知道我的回答对您是否有用,如果不对请见谅;当然,并不是您所有的问题都能从下面的代码中得到答案。我没有检查任何有关 PyCharm 提示的内容。

我已经在我的

IDE PyCharm
中执行了下面的代码,并且测试成功通过。 我更改了您的
assert
,因为我使用
unittest.mock

import unittest
from unittest.mock import create_autospec

class InterfaceB:
    def do_subtask(self, necessary_data):
        pass

class A:
  def __init__(self, some_dependency: InterfaceB):
    self.some_dependency: InterfaceB = some_dependency

  def do_thing(self, x):
    self.some_dependency.do_subtask(necessary_data=x)


class MyTestCase(unittest.TestCase):

    def test_do_thing(self):
        a: A = A(some_dependency=create_autospec(InterfaceB))
        a.do_thing(1)
        # ---> Note that I have changed your assert!
        #assert a.some_dependency.do_subtask.called_with(necessary_data=1)
        a.some_dependency.do_subtask.assert_called_once_with(necessary_data=1)

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

如您所见,我定义了一个类

InterfaceB
,并带有方法
do_subtask()

方法

test_do_thing()
仅验证:方法
do_thing(1)
的执行调用方法
do_subtask(1)
一次。

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