为了举例,假设我们正在构建一个简单的缓存。我们可以使用闭包来实现功能性方法:
makeCache = ->
c = {}
(key, fetch) ->
if c[key]
c[key]
else
c[key] = fetch()
c[key]
cache = makeCache()
cache(1, -> 1)
我发现这种方法的问题是你无法轻易测试。我希望能够检查'1'
是否在缓存中。如果我添加更多值,我想确保它们也在缓存中。
如果我有一个更复杂的缓存,比如LRU缓存,我也想测试其他方面。但是这些变量完全隐藏在闭包之后。
我倾向于使用闭包来思考解决方案,但后来我采用了面向对象的风格,以便它可以测试:
class Cache
constructor: ->
@c = {}
get: (key, fetch) ->
if c[key]
c[key]
else
c[key] = fetch()
c[key]
cache = new Cache()
cache.get(1, ->1)
现在我可以访问cache.c
以及我需要检查以测试的任何其他变量。
所以我的问题是,在使用功能样式闭包时如何测试代码?
答案 0 :(得分:2)
这不会测试您的具体情况吗?
cache = new Cache()
cache.get(1, ->1)
expect(cache.get(1, ->0)).toBe(1);
更普遍的问题是真实的。但任何封装技术都是如此。不过,我认为,测试或至少是单元测试的整个目标是处理系统的公共接口。因此,如果您没有公共工具来检查缓存中是否存在某些内容,那么您不需要对其进行单元测试。
当然有人不同意这一点,但我发现这是一条明确的分界线。