Как настроить Spring и Hibernate, чтобы мои интеграционные тесты правильно копировали поведение веб-приложения? - PullRequest
0 голосов
/ 02 декабря 2009

У нас есть веб-приложение, основанное на NSpring 1.2 и NHibernate 2, и мы используем HibernateTemplate. Веб-приложение настроено на использование OpenSessionInViewModule .

Однако в наших интеграционных тестах сеанс гибернации помечается как InitDeferredClose , и по большей части это отлично работает для наших тестов. Есть некоторые сервисные функции, которые отлично работают в контексте веб-приложения, но не работают при вызове из тестового набора.

Например: у меня есть одна функция, которая создает и обновляет ряд объектов в транзакции. Функция помечена атрибутом Transaction, но тест завершается неудачно с сообщением:

Illegal attempt to associate a collection with two open sessions

При вызове из веб-приложения транзакция успешно завершается

Как настроить весенний и спящий режим, чтобы мои интеграционные тесты правильно копировали функциональность веб-приложения?

Ответы [ 2 ]

1 голос
/ 15 января 2010

Я переписал свои тестовые данные интеграции для наследования от класса AbstractTransactionalDbProviderSpringContextTests , предоставляемого средой тестирования Spring.

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

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

1 голос
/ 24 декабря 2009

Вы должны создать экземпляр SessionScope в части теста SetUp, а затем закрыть (удалить) его в конце (TearDown). Это должно хорошо имитировать модель OSIV. Вот упрощенный пример:

using System;
using NHibernate;
using NUnit.Framework;
using Spring.Data.NHibernate.Support;

[TestFixture]
public class OsivKindOfTest
{
    private SessionScope scope;
    // get LocalSessionFactoryObject from somewhere
    // see Spring.Testing.NUnit and auto-injection
    private ISessionFactory sessionFactory;

    [SetUp]
    public void OnSetUp()
    {
        scope = new SessionScope(sessionFactory, null, true, FlushMode.Never, true);
    }

    public void TestSomething()
    {
        // just a dummy demo
        Console.WriteLine(sessionFactory.GetCurrentSession().Statistics.EntityCount);
    }

    [TearDown]
    public void TearDown()
    {
        if (scope != null)
        {
            scope.Dispose();
        }
    }
}

В этом образце предполагается, что для параметра LocalSessionFactoryObject в Spring для ExposeTransactionAwareSessionFactory установлено значение true

...