RavenDb で単体テストを行う場合、新しく追加されたデータが取得されるか、その他の方法で処理されることがよくあります。これにより、「古いインデックス」例外が発生する可能性があります。
Bulk operation cancelled because the index is stale and allowStale is false
数々の回答によると
- テスト中に古いインデックスをどのように処理する必要がありますか?
- DocumentStore ごとの WaitForNonStaleResults
- RavenDb : Denormalized Reference プロパティの値を更新する
IDocumentStore
クエリまたはバッチ操作を処理する前にインデックスが古くなくなるまでデータベース (インスタンス) を強制的に待機させる方法は、次のように初期化DefaultQueryingConsistency = ConsistencyOptions.QueryYourWrites
中に使用することです。IDocumentStore
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);
}
}