使用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