如果设置和检查依赖于未测试的方法,如何测试方法?

2024-09-27 23:27:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我创建了一个示例类(位掩码类),它有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)

我面临的问题是,所有这些测试都需要sethas方法来设置和检查位掩码中的值,但是这些方法没有经过测试。如果我不知道另一个是正确的,我就不能确定这一个是正确的。你知道吗

这个示例类不是我第一次遇到这个问题。它通常发生在我需要在类中设置和检查值/状态以测试方法时。你知道吗

我试图找到一些资源来解释这一点,但不幸的是,它们的示例只有usepurefunctions或者更改的属性可以是readdirectly。我可以通过将方法提取为纯函数,或者使用返回属性__mask的只读属性来解决这个问题。你知道吗

但这是首选方法吗?如果没有,如何测试需要使用未测试方法设置和/或检查的方法?你知道吗


Tags: 方法testself示例ondefmaskremove
2条回答

我会使用单下划线而不是双下划线,直接查看单元测试中的_mask。你知道吗

Python实际上没有私有属性或方法,甚至双下划线属性也可以在您的实例上访问,例如:obj._BitMask__mask。 如果希望子类不覆盖超类的属性,则使用双下划线。要表示“private”,应该使用单下划线。你知道吗

允许访问私有字段是python设计的一部分,因此使用这种能力responsibly并不被认为是错误的,如果您正在访问自己的类,则更是如此。你知道吗

“不要接触私有字段”背后的基本原理是,作为开发人员,您可能会弄乱类的内部结构,而且s库的私有接口也可能随时更改并破坏代码。 当您编写单元测试时,您不怕弄乱自己的类,并且接受如果更改类就必须更改单元测试,因此这种编程习惯用法对您的应用是没有用的。你知道吗

不确定这是否回答了你的问题,因为它涉及到初始类设计的改变, 但它来了。你知道吗

您创建了一个没有构造函数或属性的惰性类,它隐藏了 对象。不是sethas方法未经测试,而是 对象的状态未知。你有没有一个.value属性要透露 self.__mask,这将解决测试.set()和has()的问题。你知道吗

另外,我会强烈考虑构造函数中的默认值,这使它看起来更好看 实例化并允许更简单的测试(关于避免在pythonis here中使用setter的一些建议)。你知道吗

def __init__(self, mask=0):
    self.__mask = mask

如果有任何设计考虑因素阻止您拥有.value属性, 如果init接受一个值,也许可以使用`\uu eq\方法。你知道吗

 a = BitMask(0)     
 b = BitMask(5)     
 a.set(5)
 assert a == b     

当然,你可以在如何测试情商的问题上提出质疑。你知道吗

最后,也许你打补丁失败了,或者猴子打补丁失败了 阻止被测物体内部某物或使其以不同方式工作的技术 (如模拟网络响应而不实际调用)。任何一个库的路径 我想你还是会执行一个kind ofx.__mask = value赋值,这 对于像这里这样一个小的、好的、本地定义的类来说并不太合理。你知道吗

希望这对你的探索有所帮助。你知道吗

相关问题 更多 >

    热门问题