Fluent NHibernate - PersistenceSpecification схемы HiLo - PullRequest
5 голосов
/ 12 апреля 2011

Не уверен, что задаю правильный вопрос, поэтому, пожалуйста, потерпите меня! Немного NHibernate нуб.

Мы используем Fluent NH и используем следующую схему генерации идентификаторов для всех таблиц

public class IdGenerationConvention : IIdConvention
{
    public void Apply(IIdentityInstance instance)
    {
        var where = string.Format("TableKey = '{0}'", instance.EntityType.Name);
        instance.GeneratedBy.HiLo("HiloPrimaryKeys", "NextHighValue", "1000", x => x.AddParam("where", where));
    }
}

У нас есть SQL-скрипт, который генерирует таблицу HiloPrimaryKeys и заполняет ее данными, которые запускаются во время развертывания. Это работает нормально.

Я сейчас пытаюсь написать модульные тесты, чтобы проверить наш уровень персистентности, в идеале, используя SQLite в конфигурации памяти для скорости. Вот как я настраиваю NH для тестов:

[SetUp]
public void SetupContext()
{
    config = new SQLiteConfiguration()
            .InMemory()
            .ShowSql()
            .Raw("hibernate.generate_statistics", "true");

    var nhConfig = Fluently.Configure()
            .Database(PersistenceConfigurer)
            .Mappings(mappings =>
                 mappings.FluentMappings.AddFromAssemblyOf<DocumentMap>()
            .Conventions.AddFromAssemblyOf<IdGenerationConvention>());

    SessionSource = new SessionSource(nhConfig);
    Session = SessionSource.CreateSession();
    SessionSource.BuildSchema(Session);
}

Проблема в том, что я не знаю, как сообщить NHibernate о нашем сценарии развертывания, чтобы он генерировал правильную схему и начальные данные во время тестов.

Конкретная проблема, с которой я сталкиваюсь, заключается в выполнении следующего теста PersistenceSpecification:

[Test]
public void ShouldAddDocumentToDatabaseWithSimpleValues()
{
    new PersistenceSpecification<Document>(Session)
            .CheckProperty(x => x.CreatedBy, "anonymous")
            .CheckProperty(x => x.CreatedOn, new DateTime(1954, 12, 23))
            .CheckProperty(x => x.Reference, "anonymous")
            .CheckProperty(x => x.IsMigrated, true)
            .CheckReference(x => x.DocumentType, documentType)
            .VerifyTheMappings();
}

Который выдает следующее исключение:

TestCase ... failed: 
Execute
NHibernate.Exceptions.GenericADOException: 
        could not get or update next value[SQL: ] 
        ---> System.Data.SQLite.SQLiteException: SQLite error
        no such column: TableKey

Итак, мой вывод заключается в том, что он не запускал сценарий развертывания при проверке спецификации персистентности.

Существует ли существующее решение этой ситуации? Кажется, мой Google-фу бросил меня на этом.

Ответы [ 3 ]

4 голосов
/ 17 апреля 2011

Как сказал Брайан, вы можете запустить скрипт развертывания после построения схемы. Этот код хорошо работает для меня:

var config = new SQLiteConfiguration()
        .InMemory()
        .ShowSql()
        .Raw("hibernate.generate_statistics", "true");

var nhConfig = Fluently.Configure()
        .Database(config)
        .Mappings(mappings =>
             mappings.FluentMappings.AddFromAssemblyOf<DocumentMap>()
        .Conventions.AddFromAssemblyOf<IdGenerationConvention>());

var SessionSource = new SessionSource(nhConfig);
var Session = SessionSource.CreateSession();
SessionSource.BuildSchema(Session);

// run the deployment script
var deploymentScriptQuery = Session.CreateSQLQuery("ALTER TABLE HiloPrimaryKeys ADD COLUMN TableKey VARCHAR(255); INSERT INTO HiloPrimaryKeys (TableKey, NextHighValue) values ('Document', 1);");
deploymentScriptQuery.ExecuteUpdate();

Сценарий развертывания может быть загружен из файла и т.д. ...

Создание конфигурации FNH и схемы базы данных занимает много времени. Выполнение тестового набора займет недопустимое количество времени, если число тестов, использующих схему, увеличивается, а схема и конфигурация создаются каждым тестовым классом. Конфигурация и схема должны быть общими для всех тестов. Здесь - как этого добиться без потери тестовой изоляции.

EDIT: Если в тесте требуется более одного экземпляра сеанса, следует включить пул соединений или создать оба сеанса через одно и то же соединение. Подробности здесь ...

0 голосов
/ 16 апреля 2011

У нас есть сценарий SQL, который генерирует таблицу HiloPrimaryKeys и заполняет ее данными, которые запускаются во время развертывания.Это работает нормально.

Можете ли вы создать сопоставляемую сущность, которая представляет эту таблицу HiloPrimaryKeys, и заполнить эту таблицу до начала ваших тестов?Вы можете поместить это в базовый класс, от которого наследуются все остальные ваши тесты, чтобы вам не пришлось добавлять его в каждый класс тестирования.

Это похоже на решение Брайана, но вместо этого эта таблица будетВы выполняете автоматическое копирование точно так же, как и остальные таблицы.

0 голосов
/ 15 апреля 2011

Отказ от ответственности: я не пользователь NHibernate ...

... Но одним из возможных обходных путей будет запуск сценария развертывания (или его разновидности) в методе установки теста (используяshell execute / Process.Start) или запустить его в скрипте сборки непосредственно перед запуском этих тестов.В этом случае вам может потребоваться добавить очистку, если вы хотите обновлять базу данных при каждом тесте.

...