如何让mock-0.6返回一个值序列?

3 投票
2 回答
2720 浏览
提问于 2025-04-15 20:53

我正在使用来自http://www.voidspace.org.uk/python/mock/mock.html的mock-0.6库来模拟一个框架进行测试,我想让一个模拟的方法在每次被调用时返回一系列的值。

现在,我认为这样做应该可以:

def returnList(items):
  def sideEffect(*args, **kwargs):
    for item in items:
      yield item
    yield mock.DEFAULT
  return sideEffect

mock = Mock(side_effect=returnList(aListOfValues))
values = mock()
log.info("Got %s", values)

但是,日志输出是这样的:

subsys: INFO: Got <generator object func at 0x1021db500> 

所以,问题在于它返回的是生成器,而不是下一个值,这看起来不对。我哪里搞错了呢?

2 个回答

6

如果你只是想返回一组值,答案很简单,只要你使用的是mock==0.8.0或更高版本:

import mock 

m = mock.Mock() 
m = side_effect = [ 
    ['a', 'b', 'c'], 
    ['d', 'e', 'f'], 
] 

print "First: %s" % m() 
print "Second: %s" % m() 

输出结果是:

First: ['a', 'b', 'c']
Second: ['d', 'e', 'f']

如果你希望每次返回的值都完全一样,那答案就更简单了:

m = mock.Mock() 
m.return_value = ['a', 'b', 'c']
print m('foo') 
print m('bar') 
print m('baz') 
2

这是一个通过反复尝试找到的解决办法:

returnList 函数需要创建一个生成器,并使用它的 next 方法来提供响应:

def returnList(items):
  log.debug("Creating side effect function for %s", items)
  def func():
    for item in items:
      log.debug("side effect yielding %s", item)
      yield item
    yield mock.DEFAULT

  generator = func()

  def effect(*args, **kwargs):
    return generator.next()

  return effect

撰写回答