如果我有一个类似于下面的1的类,我想测试bar函数的各种情况,我怎样才能在不模仿私有函数的情况下完成这个?换句话说,如何在Python的unittest库中实现类似的东西:
def test_bar():
f = Foo()
f.bar(3)
expect(self._is_positive_number).toBeCalled()
foo.py
class Foo():
def bar(self, x):
if type(x) is not int:
print('Please enter a valid integer')
return False
if x > 0:
self._is_positive_number()
elif x == 0:
self._is_zero()
else
self._is_negative()
def _is_positive_number(self):
print('Positive')
return True
def _is_zero(self):
print('Zero')
return True
def _is_negative_number(self):
print('Negative')
return True
答案 0 :(得分:2)
据我所知,如果不嘲笑私有方法,就无法做到这一点。但是,mock
库(从3.3开始在标准库中以unittest.mock
形式提供,否则单独安装)使这相对无痛:
try:
# Python 3.3 or later
import unittest.mock as mock
except ImportError:
# Make sure you install it first
import mock
class TestFoo(unittest.TestCase):
def setUp(self):
self.f = Foo()
def test_bar(self):
with mock.patch.object(self.f, '_is_positive_number') as is_pos:
self.f.bar(3)
self.assertTrue(is_pos.called)
答案 1 :(得分:2)
使用mock
库是首选方法。
这是所有三种私有方法的完整示例。如果您愿意,可以选择较短的名字,但我最好保持明确。请注意,为了安全起见,您应断言不仅调用了所需的方法,而且还调用了其他私有方法:
from unittest import TestCase
from mock import Mock
class MyTestCase(TestCase):
def setUp(self):
self.instance = Foo()
self.instance._is_positive_number = Mock()
self.instance._is_negative_number = Mock()
self.instance._is_zero = Mock()
def test_positive(self):
self.instance.bar(3)
self.assertTrue(self.instance._is_positive_number.called)
self.assertFalse(self.instance._is_negative_number.called)
self.assertFalse(self.instance._is_zero.called)
def test_negative(self):
self.instance.bar(-3)
self.assertFalse(self.instance._is_positive_number.called)
self.assertTrue(self.instance._is_negative_number.called)
self.assertFalse(self.instance._is_zero.called)
def test_zero(self):
self.instance.bar(0)
self.assertFalse(self.instance._is_positive_number.called)
self.assertFalse(self.instance._is_negative_number.called)
self.assertTrue(self.instance._is_zero.called)