问题描述
我目前尝试设置一些集成测试,以验证我的 RavenDB 查询是否返回我期望的内容。
我遵循了 documentation 并启动并运行了一个测试。
当我向同一个类添加额外的测试方法时,问题就开始了。我收到以下异常:
System.InvalidOperationException : Cannot configure server after it was started. Please call 'ConfigureServer' method before any 'GetDocumentStore' is called.
所以基本上它告诉我,服务器已经在运行。但这让我感到困惑。因为 XUnit 为该类中的每个发现的测试方法创建了一个新的测试类实例。此外,它在实现 Dispose()
的任何实例上调用 IDisposable
。这是由基类 RavenTestDriver
间接实现的。
我认为正在发生的事情:
- XUnit 创建我的测试类的新实例
- XUnit 调用我的测试方法
- 我的测试方法调用
ConfigureServer
,RavenDB Embedded Server 启动 - 我的测试方法完成
- XUnit 在我的测试类实例上调用
Dispose
,RavenDB 嵌入式服务器已停止 - 冲洗并重复下一个测试方法
但我看起来,我对#5 的假设是错误的。 RavenDB 嵌入式服务器似乎从未停止过。此外,我找不到手动停止它的方法。我试图用 EmbeddedServer.Instance.Dispose()
手动处理它。但这不会改变任何事情。 (.Instance
给出了一个线索,EmbeddedServer 可能是一个单例,这可能是这里问题的一部分)。
我还尝试将 ConfigureServer
调用移动到测试类的构造函数中。由于 XUnit 为每个测试方法(就像来自 JUnit 的 setup
方法)类构造函数。但后来我得到了相同的结果。
但有趣的部分是:在两个不同的类中调用 ConfigureServer
效果很好。
我创建了一个小 reproducer repository。
那么有没有人知道如何在单元/集成测试环境中设置 RavenDB,您想针对它运行多个测试?
解决方法
从所有测试和构造函数中删除 ConfigureServer
方法。调用 GetDocumentStore()
将创建嵌入式服务器。
如果你想配置服务器,那么你应该在静态构造函数中设置它:
static MovieTests_ConfigureInConstructor()
{
ConfigureServer(new TestServerOptions() {
CommandLineArgs = new System.Collections.Generic.List<string> { "--RunInMemory=true",},FrameworkVersion = null,});
}