我是Groovy的新手。 我有一个函数,可以在其中写入要映射的值。
def addTraceEntry(key, value) {
def traceability = [:]
traceability[key] = value.trim()
println "This print happens in function addTraceEntry " + traceability
}
我还有另一个功能,需要验证以上功能是否正常工作。
def testAddTraceEntry() {
def key = 'test_key'
def value = 'test_value'
addTraceEntry(key, value)
println "This print happens in function testAddTraceEntry " + traceability
assert value == traceability[key]
}
我正在使用函数名称调用testAddTraceEntry()
函数:
testAddTraceEntry()
运行此命令时,出现错误:
This print happens in function addTraceEntry [test_key:test_value]
Caught: groovy.lang.MissingPropertyException: No such property: traceability for class: HelloWorld
groovy.lang.MissingPropertyException: No such property: traceability for class: HelloWorld
at HelloWorld.testAddTraceEntry(HelloWorld.groovy:53)
at HelloWorld.run(HelloWorld.groovy:57)
在功能testAddTraceEntry
中,它显然不知道traceability
的值,因此似乎为此提供了一个错误。
我试图返回traceability
的值。
def addTraceEntry(key, value) {
def traceability = [:]
traceability[key] = value.trim()
println "This print happens in function addTraceEntry " + traceability
return traceability
}
但这会产生相同的错误。
答案 0 :(得分:1)
看到您编写的代码后,还有很多事情值得一提。
第一件事-变量和封装的范围。让我们暂时抛弃技术性,集中精力做更重要的事情。在方法addTraceEntry
中,您可以保留一些状态,这很好。但是,方法testAddTraceEntry
的实现表明该方法试图对addTraceEntry
的实现细节有很多了解。它封装(换句话说就是)持久性逻辑(从API的角度来看,作为调用者,您不知道它在映射内持久化了键和值),这就是testAddTraceEntry
永远不应该这么做的原因假设调用此方法会改变某些结构。如果这样做,则:
第二件事-您的addTraceEntry
方法始终生成一个具有单个条目的地图。这没有多大意义,如果您调用函数,例如说4次,最终将得到4个映射,其中每个映射都包含一个映射到单个值的键。
至少有多种方法可以改善方法的实现。您可以做的最简单的事情是实现一个封装用于存储键和值的逻辑的类。考虑以下示例:
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentMap
class TraceEntriesStorage {
private final ConcurrentMap<String, Object> entries = [:] as ConcurrentHashMap
def addTraceEntry(String key, Object value) {
entries.put(key, value)
}
def containsTraceEntry(String key) {
return entries.containsKey(key)
}
def retrieveTraceEntryForKey(String key) {
return entries.get(key)
}
}
这是带有3个简短方法的简单类。它将跟踪条目存储在内部并发映射内部(以解决并发访问问题)。现在,您的测试方法可能如下所示:
def storage = new TraceEntriesStorage()
storage.addTraceEntry("test_key", "test_value")
assert storage.containsTraceEntry("test_key")
assert storage.retrieveTraceEntryForKey("test_key") == "test_value"
您创建此类的实例,添加一个条目,并检查方法containsTraceEntry
和retrieveTraceEntryForKey
是否返回期望值。如您所见,存储此跟踪条目的位置并不重要-我们实现的类的行为与预期一样重要。为了使此测试方法更好,您可以添加一个断言,以在我们实际插入test_key
之前检查是否没有跟踪条目-这样,我们知道添加跟踪条目会更改类的内部状态。但是这种方法的好处是,只要我们不违约,就可以试验和修改TraceEntriesStorage
的实现。因为最重要的是-添加跟踪条目必须允许从对象中取回它们。它的存储方式,存储位置-没关系。
希望此答案对您有所帮助,它将帮助您学习Groovy和设计更好的程序。祝您黑客愉快!
答案 1 :(得分:0)
您需要结合将return语句添加到addTraceEntry()
和将返回值分配给testAddTraceEntry()
中的变量:
def traceability = addTraceEntry(key, value)