Восстановление после ошибки nhibernate - PullRequest
1 голос
/ 18 мая 2010

Я скачал Rhino Security сегодня и начал проходить некоторые тесты. Некоторые из них, которые работают идеально изолированно, начинают получать ошибки после того, как один, который намеренно вызывает исключение, работает. Вот этот тест:

    [Test]
    public void EntitiesGroup_IfDuplicateName_Error() {
        _authorizationRepository.CreateEntitiesGroup("Admininstrators");

        _session.Flush();

        var ex = Assert.Throws<GenericADOException>(
            () =>
                {
                    _authorizationRepository.CreateEntitiesGroup("Admininstrators");
                    _session.Flush();
                }).InnerException;

        Assert.That(ex.Message, Is.StringContaining("unique"));
    }

И вот тесты и сообщения об ошибках, которые терпят неудачу:

    [Test]
    public void User_CanSave() {
        var ayende = new User {Name = "ayende"};
        _session.Save(ayende);
        _session.Flush();
        _session.Evict(ayende);

        var fromDb = _session.Get<User>(ayende.Id);
        Assert.That(fromDb, Is.Not.Null);
        Assert.That(ayende.Name, Is.EqualTo(fromDb.Name));
    }

  ----> System.Data.SQLite.SQLiteException : Abort due to constraint violation column Name is not unique


    [Test]
    public void UsersGroup_CanCreate()
    {
        var group = _authorizationRepository.CreateUsersGroup("Admininstrators");

        _session.Flush();
        _session.Evict(group);

        var fromDb = _session.Get<UsersGroup>(group.Id);
        Assert.NotNull(fromDb);
        Assert.That(fromDb.Name, Is.EqualTo(group.Name));
    }

 failed: NHibernate.AssertionFailure : null id in Rhino.Security.Tests.User entry (don't flush the Session after an exception occurs)

Does anyone see how I can reset the state of the in memory SQLite db after the first test? 

Я изменил код для использования nunit вместо xunit, так что, возможно, это также является частью проблемы.

Приветствия
Berryl

Это базовый класс, который создает экземпляр сеанса

public abstract class DatabaseFixture : IDisposable
{
    protected Account _account;
    protected IAuthorizationRepository _authorizationRepository;
    protected IAuthorizationService _authorizationService;
    protected IPermissionsBuilderService _permissionsBuilderService;
    protected IPermissionsService _permissionService;
    protected User _user;

    protected ISession _session;
    protected readonly ISessionFactory _factory;

    protected DatabaseFixture()
    {
        BeforeSetup();

        SillyContainer.SessionProvider = (() => _session);
        var sillyContainer = new SillyContainer();
        ServiceLocator.SetLocatorProvider(() => sillyContainer);

        Assert.NotNull(typeof(System.Data.SQLite.SQLiteConnection));

        var cfg = new Configuration()
            .SetProperty(Environment.ConnectionDriver, typeof(SQLite20Driver).AssemblyQualifiedName)
            .SetProperty(Environment.Dialect, typeof(SQLiteDialect).AssemblyQualifiedName)
            .SetProperty(Environment.ConnectionString, ConnectionString)
            .SetProperty(Environment.ProxyFactoryFactoryClass, typeof(ProxyFactoryFactory).AssemblyQualifiedName)
            .SetProperty(Environment.ReleaseConnections, "on_close")
            .SetProperty(Environment.UseSecondLevelCache, "true")
            .SetProperty(Environment.UseQueryCache, "true")
            .SetProperty(Environment.CacheProvider,typeof(HashtableCacheProvider).AssemblyQualifiedName)
            .AddAssembly(typeof (User).Assembly);

        Security.Configure<User>(cfg, SecurityTableStructure.Prefix);

        _factory = cfg.BuildSessionFactory();

        _session = _factory.OpenSession();

        new SchemaExport(cfg).Execute(false, true, false, _session.Connection, null);

        _session.BeginTransaction();

        SetupEntities();

        _session.Flush();
    }

    protected virtual void BeforeSetup() { }

    public virtual string ConnectionString { get { return "Data Source=:memory:"; } }

    public void Dispose()
    {
        if (_session.Transaction.IsActive)
            _session.Transaction.Rollback();
        _session.Dispose();
    }

    private void SetupEntities()
    {
        _user = new User {Name = "Ayende"};
        _account = new Account {Name = "south sand"};

        _session.Save(_user);
        _session.Save(_account);

        _authorizationService = ServiceLocator.Current.GetInstance<IAuthorizationService>();
        _permissionService = ServiceLocator.Current.GetInstance<IPermissionsService>();
        _permissionsBuilderService = ServiceLocator.Current.GetInstance<IPermissionsBuilderService>();
        _authorizationRepository = ServiceLocator.Current.GetInstance<IAuthorizationRepository>();

        _authorizationRepository.CreateUsersGroup("Administrators");
        _authorizationRepository.CreateEntitiesGroup("Important Accounts");
        _authorizationRepository.CreateOperation("/Account/Edit");


        _authorizationRepository.AssociateUserWith(_user, "Administrators");
        _authorizationRepository.AssociateEntityWith(_account, "Important Accounts");
    }
}

1 Ответ

0 голосов
/ 18 мая 2010

Как вы создаете экземпляр сеанса?

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

...