1.Stub与Mock
(1)相同点
Stub和Mock对象都是用来模拟外部依赖,使我们能控制。如果被测程序、系统或对象,我们称之为A。在测试A的过程中,A需要与程序、系统或对象B进行交互,那么Stub/Mock就是用来模拟B的行为来与A进行交互。
(2)不同点
Stub,也即“桩”,很早就有这个说法了,主要出现在集成测试的过程中,从上往下的集成时,作为下方程序的替代。作用如其名,就是在需要时,能够发现它存在,即可。就好像点名,“到”即可。
Mock,主要是指某个程序的傀儡,也即一个虚假的程序,可以按照测试者的意愿做出响应,返回被测对象需要得到的信息。也即是要风得风、要雨得雨、要返回什么值就返回什么值。
总体来说,stub完全是模拟一个外部依赖,用来提供测试时所需要的测试数据。而mock对象用来判断测试是否能通过,也就是用来验证测试中依赖对象间的交互能否达到预期。
下面用两个图来说明使用Mock和Stub在实际测试中的关注点的不同:
左图中,看到stub作为外部依赖的模拟,只需要模拟返回数据就ok了,我们的测试重点在于自身的逻辑。而右图中,通过Mock,模拟外部依赖的各种的返回值,来验证与外部依赖的交互。
2.python中mock模块使用举例
(1)未使用python mock模块的单元测试
-
# test.py
-
def add_and_multiply(x, y):
-
addition = x + y
-
multiple = multiply(x, y)
-
return (addition, multiple)
-
-
def multiply(x, y):
-
return x * y
-
-
import unittest
-
-
class MyTestCase(unittest.TestCase):
-
-
def test_add_and_multiply(self):
-
x = 3
-
y = 5
-
-
addition, multiple = add_and_multiply(x, y)
-
-
self.assertEqual( 8, addition)
-
self.assertEqual( 15, multiple)
-
-
if __name__ == "__main__":
-
unittest.main()
(2)使用python mock模块的单元测试
-
# test.py
-
import mock
-
import unittest
-
-
def add_and_multiply(x, y):
-
addition = x + y
-
multiple = multiply(x, y)
-
return (addition, multiple)
-
-
def multiply(x, y):
-
return x * y
-
-
class MyTestCase(unittest.TestCase):
-
-
-
def test_add_and_multiply(mock_multiply):
-
x = 3
-
y = 5
-
-
mock_multiply.return_value = 15
-
addition, multiple = add_and_multiply(x, y)
-
-
mock_multiply.assert_called_once_with( 3, 5)
-
self.assertEqual( 8, addition)
-
self.assertEqual( 15, multiple)
-
-
if __name__ == "__main__":
-
unittest.main()
使用“mock.patch”装饰器来用mock对象替换"multiply'。然后将它作为一个参数"mock_multiply"插入到测试代码中。在这个测试的上下文中,任何对“multiply”的调用都会被重定向到“mock_multiply”对象。
备注:
在Python2.x 中 mock是一个单独模块,需要单独安装。在Python3.x中,mock已经被集成到了unittest单元测试框架中,所以,可以直接使用。
学习资料参考于:
http://www.youkuaiyun.com/article/2015-06-01/2824821