单元测试实现 Python 属性
Unittest implementation Python property
我有一个 class 具有以下属性 clusters
:
import numpy as np
class ClustererKmeans(object):
def __init__(self):
self.clustering = np.array([0, 0, 1, 1, 3, 3, 3, 4, 5, 5])
@property
def clusters(self):
assert self.clustering is not None, 'A clustering shall be set before obtaining clusters'
return np.unique(self.clustering)
我现在想为这个简单的属性编写一个单元测试。我开始于:
from unittest import TestCase, main
from unittest.mock import Mock
class Test_clusters(TestCase):
def test_gw_01(self):
sut = Mock()
sut.clustering = np.array([0, 0, 1, 1, 3, 3, 3, 4, 5, 5])
r = ClustererKmeans.clusters(sut)
e = np.array([0, 1, 3, 4, 5])
# The following line checks to see if the two numpy arrays r and e are equal,
# and gives a detailed error message if they are not.
TestUtils.equal_np_matrix(self, r, e, 'clusters')
if __name__ == "__main__":
main()
然而,这并没有运行。
TypeError: 'property' object is not callable
我接下来将 r = ClustererKmeans.clusters(sut)
行更改为以下内容:
r = sut.clusters
但是,我又遇到了意外错误。
AssertionError: False is not true : r shall be a <class 'numpy.ndarray'> (is now a <class 'unittest.mock.Mock'>)
是否有使用单元测试框架测试 Python 中属性实现的简单方法?
直接call property你可以把你原来的代码ClustererKmeans.clusters(sut)
换成ClustererKmeans.clusters.__get__(sut)
.
即使我是一个开玩笑的热心恕我直言,这个案例也不是应用它的好例子。模拟对于从 class 和资源中删除依赖项很有用。在你的情况下 ClustererKmeans
有一个空的构造函数并且没有任何依赖关系可以打破。您可以通过以下方式完成:
class Test_clusters(TestCase):
def test_gw_01(self):
sut = ClustererKmeans()
sut.clustering = np.array([0, 0, 1, 1, 3, 3, 3, 4, 5, 5])
np.testing.assert_array_equal(np.array([0, 1, 2, 3, 4, 5]),sut.clusters)
如果你想使用模拟,你可以使用 unittest.mock.patch.object
:
来修补 ClustererKmeans()
对象
def test_gw_01(self):
sut = ClustererKmeans()
with patch.object(sut,"clustering",new=np.array([0, 0, 1, 1, 3, 3, 3, 4, 5, 5])):
e = np.array([0, 1, 3, 4, 5])
np.testing.assert_array_equal(np.array([0, 1, 2, 3, 4, 5]),sut.clusters)
...但是既然 python 给了你一个简单直接的方法,为什么还要使用补丁呢?
另一种使用模拟框架的方法应该是信任 numpy.unique
并检查 属性 是否
正确的工作:
@patch("numpy.unique")
def test_gw_01(self, mock_unique):
sut = ClustererKmeans()
sut.clustering = Mock()
v = sut.clusters
#Check is called ....
mock_unique.assert_called_with(sut.clustering)
#.... and return
self.assertIs(v, mock_unique.return_value)
#Moreover we can test the exception
sut.clustering = None
self.assertRaises(Exception, lambda s:s.clusters, sut)
对于一些错误,我深表歉意,但我没有测试代码。我你通知我,我会尽快修好。
我有一个 class 具有以下属性 clusters
:
import numpy as np
class ClustererKmeans(object):
def __init__(self):
self.clustering = np.array([0, 0, 1, 1, 3, 3, 3, 4, 5, 5])
@property
def clusters(self):
assert self.clustering is not None, 'A clustering shall be set before obtaining clusters'
return np.unique(self.clustering)
我现在想为这个简单的属性编写一个单元测试。我开始于:
from unittest import TestCase, main
from unittest.mock import Mock
class Test_clusters(TestCase):
def test_gw_01(self):
sut = Mock()
sut.clustering = np.array([0, 0, 1, 1, 3, 3, 3, 4, 5, 5])
r = ClustererKmeans.clusters(sut)
e = np.array([0, 1, 3, 4, 5])
# The following line checks to see if the two numpy arrays r and e are equal,
# and gives a detailed error message if they are not.
TestUtils.equal_np_matrix(self, r, e, 'clusters')
if __name__ == "__main__":
main()
然而,这并没有运行。
TypeError: 'property' object is not callable
我接下来将 r = ClustererKmeans.clusters(sut)
行更改为以下内容:
r = sut.clusters
但是,我又遇到了意外错误。
AssertionError: False is not true : r shall be a <class 'numpy.ndarray'> (is now a <class 'unittest.mock.Mock'>)
是否有使用单元测试框架测试 Python 中属性实现的简单方法?
直接call property你可以把你原来的代码ClustererKmeans.clusters(sut)
换成ClustererKmeans.clusters.__get__(sut)
.
即使我是一个开玩笑的热心恕我直言,这个案例也不是应用它的好例子。模拟对于从 class 和资源中删除依赖项很有用。在你的情况下 ClustererKmeans
有一个空的构造函数并且没有任何依赖关系可以打破。您可以通过以下方式完成:
class Test_clusters(TestCase):
def test_gw_01(self):
sut = ClustererKmeans()
sut.clustering = np.array([0, 0, 1, 1, 3, 3, 3, 4, 5, 5])
np.testing.assert_array_equal(np.array([0, 1, 2, 3, 4, 5]),sut.clusters)
如果你想使用模拟,你可以使用 unittest.mock.patch.object
:
ClustererKmeans()
对象
def test_gw_01(self):
sut = ClustererKmeans()
with patch.object(sut,"clustering",new=np.array([0, 0, 1, 1, 3, 3, 3, 4, 5, 5])):
e = np.array([0, 1, 3, 4, 5])
np.testing.assert_array_equal(np.array([0, 1, 2, 3, 4, 5]),sut.clusters)
...但是既然 python 给了你一个简单直接的方法,为什么还要使用补丁呢?
另一种使用模拟框架的方法应该是信任 numpy.unique
并检查 属性 是否
正确的工作:
@patch("numpy.unique")
def test_gw_01(self, mock_unique):
sut = ClustererKmeans()
sut.clustering = Mock()
v = sut.clusters
#Check is called ....
mock_unique.assert_called_with(sut.clustering)
#.... and return
self.assertIs(v, mock_unique.return_value)
#Moreover we can test the exception
sut.clustering = None
self.assertRaises(Exception, lambda s:s.clusters, sut)
对于一些错误,我深表歉意,但我没有测试代码。我你通知我,我会尽快修好。