Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 测试类范围属性_Python_Unit Testing_Class_Python Unittest - Fatal编程技术网

Python 测试类范围属性

Python 测试类范围属性,python,unit-testing,class,python-unittest,Python,Unit Testing,Class,Python Unittest,假设我有一个名为foo的模块,其中有一个类BarBar有一个类范围的计数器属性,允许我跟踪创建实例的顺序foo看起来像这样: from itertools import count class Bar: class_count = count(0) def __init__(self): self.id = self.class_count.next() class TestBar(...): def setUp(...) ... self

假设我有一个名为
foo
的模块,其中有一个类
Bar
Bar
有一个类范围的计数器属性,允许我跟踪创建实例的顺序
foo
看起来像这样:

from itertools import count

class Bar:
    class_count = count(0)
    def __init__(self):
        self.id = self.class_count.next()
class TestBar(...):
  def setUp(...)
    ...
    self.bar = BarStub()

  def test_foo_should_blah_when_blah(self):
    with mock.patch.object(self.bar, 'count_class', side_effect=[...]) as mock_count:
      actual = self.bar.unit_under_test(...)
      mock_count.assert_called_with([...])
现在我有了一个测试文件,我正在测试
Bar
的各种功能。我不确定如何测试这个
id
属性,因为其他单元测试正在创建
Bar
的实例,因此我不知道
Bar
实例的给定id应该是什么。此外,我的类的这种行为意味着我的单元测试彼此独立,这是不可取的。我应该如何构造单元测试以使测试彼此独立?

您可以使用来保护当前计数,然后临时重置计数。然后,再次恢复原始状态:

from itertools import count
import unittest

class Bar:
    class_count = count(0)
    def __init__(self):
        self.id = next(self.class_count)


class TestBar(unittest.TestCase):
    def setUp(self):
        self.nxtcount = next(Bar.class_count)  # safe current state
        Bar.class_count = count(0)             # reset to 0

    def tearDown(self):
        Bar.class_count = count(self.nxtcount) # reset to old state

    def teststh1(self):
        x = Bar()
        self.assertEqual(x.id, 0)

    def teststh2(self):
        x1 = Bar()
        x2 = Bar()
        x3 = Bar()
        self.assertEqual(x1.id, 0)
        self.assertEqual(x2.id, 1)
        self.assertEqual(x3.id, 2)

这确保每个测试方法都以一个
条开始。class\u count
为0。

我会去掉条以绕过构造函数

class BarStub(Bar):
  def __init__(self):
    self.class_count = None
    self.id = None
现在您可以这样进行测试:

from itertools import count

class Bar:
    class_count = count(0)
    def __init__(self):
        self.id = self.class_count.next()
class TestBar(...):
  def setUp(...)
    ...
    self.bar = BarStub()

  def test_foo_should_blah_when_blah(self):
    with mock.patch.object(self.bar, 'count_class', side_effect=[...]) as mock_count:
      actual = self.bar.unit_under_test(...)
      mock_count.assert_called_with([...])

这很可能回答了你的问题:这里的问题是:测试什么?基本上,您只需要测试是否调用了计数器的下一个方法。测试计数器的功能不是你的工作。因此,模拟计数器并断言模拟是否按预期调用。