我正在研究一个库,该库在应用程序启动期间查找源代码树中的依赖项,并且我正在尝试编写集成测试以确保其正常工作。我的测试命名空间中有夹具文件,测试开始并成功即可。
为了确保测试不会影响将来的运行,我添加了一个"after"处理程序(midje),它使用 remove-ns
来删除测试装置命名空间。
在下一次加载时,测试将失败,因为缺少命名空间。
似乎remove-ns
不仅删除了命名空间,而且之后无法使用require
将其加载到同一正在运行的 VM 中。我注意到remove-ns
有一个"谨慎使用"的说明,没有解释。
我已经验证了手动运行require
似乎确实无法重新加载已删除的命名空间:
user=>(test.util.fixtures.A/f)
{:item 1}
user=> (remove-ns 'test.util.fixtures.A)
#<Namespace test.util.fixtures.A>
user=> (test.util.fixtures.A/f)
ClassNotFoundException test.util.fixtures.A
user=> (require 'test.util.fixtures.A)
nil
user=> (test.util.fixtures.A/f)
ClassNotFoundException test.util.fixtures.A
有人明白为什么会这样吗?
我通过源代码进行了跟踪,最终需要调用load-libs,而load-libs又调用load-libs,而加载lib又检查全局原子(该行loaded (contains? @*loaded-libs* lib)
)。
进一步阅读,似乎一旦加载了某些内容,您就可以为库加载器指定:reload
选项。现在我记得看到:reload
,所以解决方案是将:reload
放入要求中:
user=> (require 'test.util.fixtures.A :reload)
nil
user=> (test.util.fixtures.A/f)
{:item 1}