我已經寫了一個小的輔助模塊,它允許正是這一點:嵌套函數
例子:
def f(v1):
v2 = 1
def g(v3=2):
return v1 + v2 + v3 + 4
def h():
return 16
return g() + h() + 32
class C(object):
def foo(self):
def k(x):
return [ self, x ]
return k(3)
def m():
vm = 1
def n(an=2):
vn = 4
def o(ao=8):
vo = 16
return vm + an + vn + ao + vo
return o()
return n()
這些可以使用這種類型的代碼進行單元測試:
import unittest
from nested import nested
class TestNested(unittest.TestCase):
def runTest(self):
nestedG = nested(f, 'g', v1=8, v2=1)
self.assertEqual(nestedG(2), 15)
nestedH = nested(f, 'h')
self.assertEqual(nestedH(), 16)
nestedK = nested(C.foo, 'k', self='mock')
self.assertEqual(nestedK(5), [ 'mock', 5 ])
nestedN = nested(m, 'n', vm=1)
nestedO = nested(nestedN, 'o', vm=1, an=2, vn=4)
self.assertEqual(nestedO(8), 31)
def main(argv):
unittest.main()
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv))
小助手模塊nested
看起來像這樣:
import types
def freeVar(val):
def nested():
return val
return nested.__closure__[0]
def nested(outer, innerName, **freeVars):
if isinstance(outer, (types.FunctionType, types.MethodType)):
outer = outer.func_code
for const in outer.co_consts:
if isinstance(const, types.CodeType) and const.co_name == innerName:
return types.FunctionType(const, globals(), None, None, tuple(
freeVar(freeVars[name]) for name in const.co_freevars))
這個問題如何回答?是否有很好的解決方案來隔離單元測試的這些內部函數?即使沒有從外部函數對象訪問內部函數,也可能通過使用python模塊解析器,ast或tokenizer來實現代碼本身。顯然這比編碼更容易。 :-) – 2011-07-09 16:02:06
它回答了這個問題,因爲沒有*測試私人的實現細節。你可以依靠測試覆蓋工具來告訴你,如果你測試的公共接口充分行使私有實現。 – SingleNegationElimination 2011-07-09 16:24:50