使用RavenDb进行单元测试时,通常会检索或处理新增的数据。这可能导致“陈旧索引”例外,例如RavenDb:强制索引等待,直到单元测试时才失效
Bulk operation cancelled because the index is stale and allowStale is false
根据一些答案
- How should stale indexes be handled during testing?
- WaitForNonStaleResults per DocumentStore
- RavenDb : Update a Denormalized Reference property value
迫使数据库的方式(在IDocumentStore
实例)的等待,直到它的索引在处理之前不会陈旧查询或批处理操作是IDocumentStore
初始化过程中使用DefaultQueryingConsistency = ConsistencyOptions.QueryYourWrites
,像这样:
public class InMemoryRavenSessionProvider : IRavenSessionProvider
{
private static IDocumentStore documentStore;
public static IDocumentStore DocumentStore
{
get { return (documentStore ?? (documentStore = CreateDocumentStore())); }
}
private static IDocumentStore CreateDocumentStore()
{
var store = new EmbeddableDocumentStore
{
RunInMemory = true,
Conventions = new DocumentConvention
{
DefaultQueryingConsistency = ConsistencyOptions.QueryYourWrites,
IdentityPartsSeparator = "-"
}
};
store.Initialize();
IndexCreation.CreateIndexes(typeof (RavenIndexes).Assembly, store);
return store;
}
public IDocumentSession GetSession()
{
return DocumentStore.OpenSession();
}
}
不幸的是,上面的代码不起作用。我仍然收到过时索引的例外情况。这些可以通过投入虚拟查询来解决,其中包括.Customize(x => x.WaitForNonStaleResultsAsOfLastWrite())
。
这很好,只要这些可以包含在单元测试中,但如果它们不能?我发现这些WaitForNonStaleResults*
调用正在进入生产代码,所以我可以通过单元测试。
那么,有没有一种可靠的方法,使用最新版本的RavenDb,在允许处理命令之前强制索引变得清新 - 仅用于单元测试?
编辑1
这是基于答案给出低于强制等到指数不陈旧的解决方案。为了方便单元测试,我将它写成扩展方法;
public static class IDocumentSessionExt
{
public static void ClearStaleIndexes(this IDocumentSession db)
{
while (db.Advanced.DatabaseCommands.GetStatistics().StaleIndexes.Length != 0)
{
Thread.Sleep(10);
}
}
}
这里是已使用详细WaitForNonStaleResultsAsOfLastWrite
技术单元测试,但现在使用更简洁扩展方法。
[Fact]
public void Should_return_list_of_Relationships_for_given_mentor()
{
using (var db = Fake.Db())
{
var mentorId = Fake.Mentor(db).Id;
Fake.Relationship(db, mentorId, Fake.Mentee(db).Id);
Fake.Relationship(db, mentorId, Fake.Mentee(db).Id);
Fake.Relationship(db, Fake.Mentor(db).Id, Fake.Mentee(db).Id);
//db.Query<Relationship>()
// .Customize(x => x.WaitForNonStaleResultsAsOfLastWrite())
// .Count()
// .ShouldBe(3);
db.ClearStaleIndexes();
db.Query<Relationship>().Count().ShouldBe(3);
MentorService.GetRelationships(db, mentorId).Count.ShouldBe(2);
}
}
现在这是举行反对DocumentStore而非DocumentSession,所以扩展方法会改变使用类似db.Advanced.DocumentStore.DatabaseCommands。 GetStatistics().StaleIndexes.Any(),或者直接将DocumentStore直接放入,如果可以的话 – adrian 2014-08-12 15:12:20