RavenDb :Принудительное ожидание индексов до тех пор, пока они не устареют во время модульного тестирования.

При модульном тестировании с RavenDb часто бывает так, что вновь добавленные данные извлекаются или обрабатываются иным образом. Это может привести к исключениям «устаревшего индекса», например.

Bulk operation cancelled because the index is stale and allowStale is false

Согласно ряду ответов

Способ заставить базу данных (экземпляра 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()
        // .Customize(x => x.WaitForNonStaleResultsAsOfLastWrite())
        // .Count()
        // .ShouldBe(3);

        db.ClearStaleIndexes();
        db.Query().Count().ShouldBe(3);
        MentorService.GetRelationships(db, mentorId).Count.ShouldBe(2);
    }
}

24
задан Community 23 May 2017 в 12:26
поделиться