我创建了一个示例类(一个位掩码类),它有4个非常简单的函数。我还为这个班级创建了一个单元测试。
import unittest
class BitMask:
def __init__(self):
self.__mask = 0
def set(self, slot):
self.__mask |= (1 << slot)
def remove(self, slot):
self.__mask &= ~(1 << slot)
def has(self, slot):
return (self.__mask >> slot) & 1
def clear(self):
self.__mask = 0
class TestBitmask(unittest.TestCase):
def setUp(self):
self.bitmask = BitMask()
def test_set_on_valid_input(self):
self.bitmask.set(5)
self.assertEqual(self.bitmask.has(5), True)
def test_has_on_valid_input(self):
self.bitmask.set(5)
self.assertEqual(self.bitmask.has(5), True)
def test_remove_on_valid_input(self):
self.bitmask.set(5)
self.bitmask.remove(5)
self.assertEqual(self.bitmask.has(5), False)
def test_clear(self):
for i in range(16):
self.bitmask.set(i)
self.bitmask.clear()
for j in range(16):
with self.subTest(j=j):
self.assertEqual(self.bitmask.has(j), False)
我遇到的问题是所有这些测试都需要set
和has
方法来设置和检查位掩码中的值,但这些方法都是未经测试的。我不能确定一个是正确的而不知道另一个是。
这个示例类不是我第一次遇到这个问题。当我需要在类中设置和检查值/状态以测试方法时,通常会发生这种情况。
我试图找到解释此问题的资源,但遗憾的是他们的示例只有use pure functions或更改的属性可以是read {{3} }。我可以通过将方法提取为纯函数或使用返回属性__mask
的只读属性来解决问题。
但这是首选方法吗?如果没有,我如何测试需要使用未经测试的方法设置和/或检查的方法?
答案 0 :(得分:2)
不确定这会回答您的问题,因为它涉及更改初始课程设计, 但它就在这里。
你创建一个没有构造函数或属性的惰性类,它隐藏了你的状态
宾语。它不是未经测试的set
或has
方法,而是问题
对象的状态未知。您是否有.value
属性要透露
self.__mask
,这将解决测试.set()和has()的问题。
此外,我强烈考虑构造函数中的默认值,这使它看起来更好看 即时化并允许更容易的测试(关于在python is here中避免setter的一些建议)。
def __init__(self, mask=0):
self.__mask = mask
如果有任何设计考虑因素阻止您拥有.value
属性,
如果__init__接受一个值,也许可以使用`__eq__方法。
a = BitMask(0)
b = BitMask(5)
a.set(5)
assert a == b
当然,你可以挑战__eq__tested本身的方式。
最后,也许你在修补或猴子修补的情况下失败了 - a
阻止被测对象内部某些东西或使其工作方式不同的技术
(例如,模仿网络响应,无需实际通话)。使用任何用于路径的库
我认为你仍然会最终执行kind of
x.__mask = value
分配
对于像这里一样的小型,漂亮且本地定义的类来说,这不太合理。
希望它有助于您所探索的内容。
答案 1 :(得分:0)
我会使用单个下划线而不是double,只是直接查看单元测试中的_mask
。
Python实际上没有私有属性或方法,甚至可以在您的实例上访问双下划线属性,如下所示:obj._BitMask__mask
。
如果希望子类不覆盖超类的属性,则使用双下划线。要表示“私人”,您应该使用单个下划线。
允许访问私有字段是python设计的一部分,因此使用此功能responsibly并不被认为是错误的,如果您正在访问您自己的类,则更是如此。
背后的理由&#34;不要触摸私人领域&#34;是因为你作为开发人员可以搞乱类的内部,s库的私有接口可以随时改变并破坏你的代码。 当你编写单元测试时,你不怕搞乱你自己的课程,并且如果你改变你的课程就接受你必须改变单元测试,所以这个编程习惯对你来说没用。