2010-05-18 4 views
1

오늘 Rhino Security를 ​​다운로드하고 일부 테스트를 시작했습니다. 의도적으로 예외를 발생시키는 오류가 발생하기 시작하면 오류가 발생하기 시작합니다. 나는 그 여기에 문제의 일부입니다 그래서 아마 대신 xUnit의의 NUNIT를 사용하도록 코드를 변경nhibernate 오류 복구

[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? 

:

[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")); 
    } 

그리고 여기에 실패 테스트 및 오류 메시지가 있습니다 : 여기에 테스트입니다 잘.

건배,
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"); 
    } 
} 
+0

새 세션의 시작과 SQLite db를 Setup 메서드로 추출한 다음 _session.Dispose를 Teardown 메서드에 넣어 모든 테스트가 실행되도록했습니다. Ayende & XUnit이 어떻게이 작업을했는지 누군가가 알 수 있도록하기 위해이 부분을 조금 열어 두겠습니다. 건배 – Berryl

답변

0

어떻게 세션을 인스턴스화되어 있습니까?

예외가있을 때마다 세션을 폐기해야합니다. 즉, 테스트 방법간에 세션을 거의 공유하지 않아야 함을 의미합니다.

+0

기본 클래스의 ctor에서 세션을 인스턴스화하는 Ayende의 코드는 원래 게시물의 끝에 있습니다. 건배 – Berryl

+0

Ayende는 각 테스트 후에 세션을 삭제하지만, 개인적으로 더 익숙한 NUnit Teardown 방법과 달리 XUnit과 IDisposable 기본 고정 장치를 사용하여 세션을 삭제합니다. 이것은 db를 재생성하는 것이 빠르기 때문에 SQLite에 대해 의미가 있습니다. '실제'db를 사용할 때 테스트에서 볼 수있는 대안은 트랜잭션마다 시작하고 롤백하는 것입니다. – Berryl