【问题标题】:Python: mock patch class once for all test methods?Python:为所有测试方法模拟一次补丁类?
【发布时间】:2019-08-22 06:30:05
【问题描述】:

考虑这个例子:

module.py:

class LST:
    x = [1]


class T:
    def __init__(self, times):
        self.times = times

    def t1(self):
        return LST.x * self.times

    def t2(self):
        return LST.x * (self.times+1)

    def t3(self):
        return LST.x * (self.times+2)

test.py:

from mock import patch

import unittest
import module


@patch('module.LST')
class TestM(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        super(TestM, cls).setUpClass()
        cls.t = module.T(1)

    def test_01(self, LST):
        LST.x = [2]
        self.assertEqual([2], self.t.t1())

    def test_02(self, LST):
        LST.x = [2]
        self.assertEqual([2, 2], self.t.t2())

    def test_03(self, LST):
        LST.x = [2]
        self.assertEqual([2, 2, 2], self.t.t3())

我只想用补丁修改LST 类,因为相同的修改将用于所有测试。

是否可以只修改一次,然后将其用于所有方法?所以我不需要在每个方法调用上重复LST.x = [2] 吗?

【问题讨论】:

  • 您是否还会考虑使用 pytest 而不是 unittest 的答案?
  • @Arne 不,它需要进行单元测试。我使用的是默认使用 unittest 的框架,因此更改它会很不方便。

标签: python mocking python-unittest python-mock


【解决方案1】:

怎么样:

from mock import patch

import unittest
import module


class TestM(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        super(TestM, cls).setUpClass()
        cls.t = module.T(1)
        cls.patcher = patch('module.LST')
        LST = cls.patcher.start()
        LST.x = [2]

    @classmethod
    def tearDownClass(cls):
        cls.patcher.stop()

    def test_01(self):
        self.assertEqual([2], self.t.t1())

    def test_02(self):
        self.assertEqual([2, 2], self.t.t2())

    def test_03(self):
        self.assertEqual([2, 2, 2], self.t.t3())

基本思想是您可以手动控制修补行为。

【讨论】:

  • 这是一个很好的解决方案。正是我需要的,谢谢。
  • 为了完整起见,我建议在tearDownClass 上添加super,因为如果您在不调用super 的情况下覆盖tearDownClass,在相同的情况下可能会导致意想不到的后果。
猜你喜欢
  • 2017-11-15
  • 2019-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-17
  • 1970-01-01
相关资源
最近更新 更多