【发布时间】:2011-03-25 12:25:33
【问题描述】:
我正在使用 ScalaTest 测试我用 Scala 编写的解析器。解析器一次处理一个文件,它有一个单例对象,如下所示:
class Parser{...}
object Resolver {...}
我写的测试用例有点像这样
describe("Syntax:") {
val dir = new File("tests\\syntax");
val files = dir.listFiles.filter(
f => """.*\.chalice$""".r.findFirstIn(f.getName).isDefined);
for(inputFile <- files) {
val parser = new Parser();
val c = Resolver.getClass.getConstructor();
c.setAccessible(true);
c.newInstance();
val iserror = errortest(inputFile)
val result = invokeparser(parser,inputFile.getAbsolutePath) //local method
it(inputFile.getName + (if (iserror)" ERR" else " NOERR") ){
if (!iserror) result should be (ResolverSuccess())
else if(result.isInstanceOf[ResolverError]) assert(true)
}
}
}
现在在每次迭代中,单例对象 Resolver 中先前迭代的副作用不会被清除。
有没有办法指定scalatest模块重新初始化单例对象?
更新:根据 Daniel 的建议,我更新了代码,还添加了更多细节。
更新:显然是解析器在做一些可疑的事情。在随后的调用中,它不会丢弃先前的 AST。奇怪的。由于这是题外话,我会挖掘更多,可能会使用单独的线程进行讨论,谢谢大家的回答
最终更新:问题出在 Resolver 以外的单例对象上,它位于其他文件中,所以我不知何故错过了它。我能够使用 Daniel Spiewak 的回复解决这个问题。这是一种肮脏的做事方式,但考虑到我的情况以及我正在编写测试代码的事实,这也是唯一的事情,它不会投入生产使用。
【问题讨论】:
-
R里面有没有清理方法,还是希望重新创建? -
R 中没有清理方法,我无法更改代码。你能在 Scala 中重新创建单例对象吗?
-
不。他们是严格的单身人士。按需初始化(由 JVM 的类加载决定),然后永久初始化。当然,它们可以具有可变的内部状态,就像任何 Scala 类一样。
-
假设 Parser 被硬编码为引用常规 Resolver 单例实例,您的更改将不起作用。您正在使用 Daniel 建议的偷偷摸摸的技巧在此处创建它的新实例(然后建议您永远不要使用)。如果 Parser 真的是这样设计的,它使用对 Resolver 的硬编码引用来维护状态(不是一个非常可测试的设计),那么您需要做的是为每个测试加载 Resolver 和 Parser,并使用自定义类加载器。我会在回复中发布。