接下来介绍下OpenStack中关于这两种python 测试框架的常见使用
  1. [mox] StubOutWithMock
  在OpenStack的test code中我们经常看到mox中使用StubOutWithMock, 这个function做的事情是用mock对象替掉一些方法或者属性. 见下例,摘自OpenStack中代码片段,用来说明StubOutWithMock用法。
  self.mox.StubOutWithMock(quota.QUOTAS, "reserve")
  quota.QUOTAS.reserve(self.context, instances=40,cores=mox.IsA(int),ram=mox.IsA(int)).AndRaise(quota_exception) #mox.IsA是测试基本数据或对象类型的
  self.mox.ReplayAll()
  function(...) #这里简单化了这个方法, 它是调用过quota.QUOTAS.reserve的一个function,
  #也即是我们需要测试的function
  2.[mock] mock.patch & mock.patch.object
  这两者用于把对象class, function, attribute  做成一个mock.
  从定义上可以看出两者之间的差别
  mock.patch(target, ...)
  mock.patch.object(target, attribute, ...)
  前者给target做mock, 这个target可以是class, function
  后者给target上的attribute作mock, 一般使用中用的比较多的是对象上的function.
  具体实现上, 两者都可以有两种写法, 一种叫decorators, 利用python中的装饰@, 另一种用with语句, 下面是随便写的一个例子
  随便定义一个简单的func()来被测试
class A(object):
def func(self):
return B.getFromDB('b')
class B(object):
def getFromDB(self, param):
...
  具体的测试方法如下
"""第一种写法, decorators方式, 采用mock.patch模拟一个方法.
当有多个方法时注意一点是参数的顺序, 如
@mock.patch('B.getFromDB')
@mock.patch('B.getFromXX')
def test_func(self, mock_getFromXX, mock_getFromDB):
可以看到后@的对象在参数列表中在前面, 这个是由于@的执行顺序为@mock.patch('B.getFromDB')(@mock.patch('B.getFromXX')(func)) 决定的
"""
@mock.patch('B.getFromDB')
def test_func(self, mock_getFromDB):
mock_getFromDB.return_value = '1'
self.assertEqual('1', A.func())
"""第二种写法 ,decorators方式, 采用mock.patch. object模拟一个方法.
"""
@mock.patch.object(B, 'getFromDB')
def test_func(self, mock_getFromDB):
mock_getFromDB.return_value = '1'
self.assertEqual('1', A.func())
"""第三种写法, with statement, 采用mock.patch模拟一个方法.
"""
def test_func(self, mock_getFromDB):
with mock.patch('B.getFromDB') as mock_getFromDB:
mock_getFromDB.return_value = '1'
self.assertEqual('1', A.func())
"""第四种写法, with statement, 采用mock.patch.object模拟一个方法.
"""
def test_func(self, mock_getFromDB):
with mock.patch.object(B, 'getFromDB') as mock_getFromDB:
mock_getFromDB.return_value = '1'
self.assertEqual('1', A.func())
  上面的例子中, 关于mock.patch模拟的都是function, 没有针对class, 下面是mock.patch document 给出的例子,
>>> class Class(object):
...     def method(self):
...         pass
...
>>> with patch('__main__.Class') as MockClass:
...     instance = MockClass.return_value #本例中模拟了'__main__.Class'这个class, 现把模拟结果赋给intance来测试
...     instance.method.return_value = 'foo' #模拟对象和原class有相同的atribute, 故模拟对象也由method()函数, 可以模拟其返回值
...     assert Class() is instance
...     assert Class().method() == 'foo'
  它模拟class, 在OpneStack各个component中现在用的不多.