【问题标题】:Why are instances of my mocked class sharing attributes?为什么我的模拟类的实例共享属性?
【发布时间】:2020-07-24 17:55:49
【问题描述】:

我有以下 3 个文件:

shape.py

import danger_import

class Polygon:
  def __init__(self, height=10, width=10):
    self.height = height
    self.width = width
    self.isActive = False

  def activate():
    self.isActive = True

polygon_utility.py

import shape

poly1 = None
poly2 = None

def activate_polygon():
  poly1.activate()
  if False:
    poly2.activate()

if __name__ != '__main__':
  poly1 = shape.Polygon()
  poly2 = shape.Polygon(4,12)

test_polygon_utility.py

import pytest
import sys
from unittest import mock

sys.modules['danger_import'] = mock.MagicMock()
import polygon_utility
import shape

@mock.patch('shape.Polygon')
def test_activate_polygon(mock_poly):
  polygon_utility.poly1 = mock_poly()
  polygon_utility.poly2 = mock_poly(4,12)
  polygon_utility.activate_polygon()
  assert polygon_utility.poly1.activate.call_count == 1
  assert polygon_utility.poly2.activate.call_count == 0

基本上我有这个多边形类,我将从中创建几个多边形。多边形实用程序根据我没有包含的一些逻辑来管理多个多边形。我打算对 activate_polygon 函数进行单元测试,该函数依赖于现有的多边形对象。为此,我正在导入形状文件,以便创建 Polygon 类的模拟实例。然后我将它们分配给我正在单元测试的文件中的全局变量 poly1 和 poly2,并尝试运行该函数。

当我运行这个单元测试时,第二个断言失败。似乎由于某种原因,我创建的 2 个多边形实例被捆绑在一起。谁能向我解释为什么会这样以及我将如何获得我想要的行为?

【问题讨论】:

    标签: python python-3.x unit-testing mocking


    【解决方案1】:

    您的 @mock.patch 装饰器正在模拟 Polygon 的构造函数。然后,您将 poly1poly2 分配给该构造函数的调用。构造函数的返回值将是相同的;它们都是mock_poly.return_value,这就是poly2的激活调用计数> 0的原因。

    有几种方法可以做到这一点,但这里使用全局变量令人担忧。通过模拟全局变量,您将在整个测试运行时修改它们的值,因此您的结果可能会有所不同并且出乎意料。所以,我鼓励你看看重构 polygon_utility.py 是如何完成的。在短期内,我认为您可以通过以下方式解决您的模拟/断言问题:

    @mock.patch('shape.Polygon')
    def test_activate_polygon(mock_poly):
        polygon_utility.poly1 = mock.Mock()
        polygon_utility.poly2 = mock.Mock()
        polygon_utility.activate_polygon()
        assert polygon_utility.poly1.activate.call_count == 1
        assert polygon_utility.poly2.activate.call_count == 0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-23
      • 1970-01-01
      • 2016-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-21
      相关资源
      最近更新 更多