我目前尝试设置一些集成测试,以验证我的 RavenDB 查询是否返回我期望的结果。
我按照文档进行操作并进行了一次测试。
当我向同一个类添加额外的测试方法时,问题就开始了。我收到以下异常:
System.InvalidOperationException : Cannot configure server after it was started. Please call 'ConfigureServer' method before any 'GetDocumentStore' is called.
所以基本上它告诉我,服务器已经在运行。但这让我很困惑。由于 XUnit 为该类中每个发现的测试方法创建了一个新的测试类实例。此外,它在任何实现
Dispose()
的实例上调用 IDisposable
。这是由基类间接实现的RavenTestDriver
。
所以我认为正在发生的事情:
ConfigureServer
,RavenDB嵌入式服务器启动了Dispose
,RavenDB 嵌入式服务器已停止但我看起来,我对#5 的假设是错误的。 RavenDB嵌入式服务器似乎从未停止过。另外我找不到手动停止它的方法。我试图用
EmbeddedServer.Instance.Dispose()
手动处理它。但这并没有改变任何事情。 (.Instance
给出了一个线索,嵌入式服务器可能是一个单例,这可能是这里问题的一部分)。
我还尝试将
ConfigureServer
调用移至测试类的构造函数中。由于 XUnit 类为每个测试方法构建了构造函数(就像 JUnit 中的 setup
方法)。但后来我得到了相同的结果。
但有趣的是:在两个不同的类中调用
ConfigureServer
效果很好。
我创建了一个小型的 re Producer 存储库。
那么有人知道如何在单元/集成测试环境中设置 RavenDB 并对其运行多个测试吗?
从所有测试和构造函数中删除
ConfigureServer
方法。调用 GetDocumentStore()
将创建嵌入式服务器。
如果你想配置服务器,那么你应该在静态构造函数中设置它:
static MovieTests_ConfigureInConstructor()
{
ConfigureServer(new TestServerOptions() {
CommandLineArgs = new System.Collections.Generic.List<string> { "--RunInMemory=true", },
FrameworkVersion = null,
});
}
万一三年后有人来到这里,这是我们在我们公司实施的解决方案(仅用于测试目的):
第3点是关键。由于我们所有的测试都共享这个公共基测试类,因此它们都运行它的构造函数。可以在那里执行ConfigureServer()方法,但每次非第一次运行都会失败。
因此我们为基类创建了一个名为 IsServerAlreadyConfigured 的静态属性。我们只在它为 false 时调用ConfigureServer(),并立即将其设置为 true。所有后续执行都不会尝试配置服务器。
我在这里粘贴解决方案和我们遇到的错误,以防它引导某人进入此页面,因为我花了很长时间才找到这个和我们的解决方案。
错误1:缺少许可证
The RavenDB server cannot start due to a missing license. Please review the details below to resolve the issue:
错误 1 可以通过将服务器配置为忽略此问题来解决,如 RavenDb 文档中(巧妙地)指定的那样。
错误2:配置已经运行的服务器
System.InvalidOperationException: Cannot configure server after it was started. Please call 'ConfigureServer' method before any 'GetDocumentStore' is ...
We attempted to obtain a valid license using the configuration key 'License', but this process was not successful for the following reason:
我们的解决方案:
public class BaseRavenTestDriver : RavenTestDriver
{
protected readonly IDocumentStore DocumentStore;
private static bool IsAlreadyConfigured { get; set; }
protected BaseRavenTestDriver()
{
// We need to do this only once, otherwise an exception is thrown since the server cannot be configured after starting it.
if (!IsAlreadyConfigured)
{
ConfigureServer(new TestServerOptions
{
Licensing = new ServerOptions.LicensingOptions
{ThrowOnInvalidOrMissingLicense = false}
});
IsAlreadyConfigured = true;
}
DocumentStore = GetDocumentStore(null, Guid.NewGuid().ToString());
}
}