我有一個類,任務,它有一個屬性TaskLibrary這是它會加載和運行一些代碼。所以,任何任務都有一個庫,但是任何庫都可以有很多任務。我的問題是,我的測試確保任務的庫屬性不爲null是失敗的(所以它可能只是我的測試)。我的類是有效的:幫助我測試與NHibernate和NUnit的一對多的realtionship
public class Task
{
public virtual int TaskId {get;set;}
public virtual string Locked {get;set;}
public virtual int Status {get;set;}
public virtual TaskLibrary Library {get;set;}
}
public class TaskLibrary
{
public virtual int LibraryId {get;set}
public virtual string Name {get;set;}
public virtual string Description {get;set;}
public virtual byte[] Dll {get;set}
public virtual IEnumerable<Task> Tasks {get;set;}
}
我NHibernate的映射是這樣的:
<class name="Task">
<id name="Id" column="TaskId" type="Int32" unsaved-value="-1">
<generator class="identity"/>
</id>
<property name="Locked" column="Locked"/>
<property name="Status" column="Status"/>
<many-to-one name="Library" class="TaskLibrary" fetch="join"/>
</class>
<class name="TaskLibrary">
<id name="Id" column="LibraryId">
<generator class="identity"/>
</id>
<property name="Name"/>
<property name="Description"/>
<property name="Dll"/>
<set name="Tasks" lazy="true">
<key column="LibraryId"/>
<one-to-many class="Task"/>
</set>
</class>
我的測試類是這樣的:
[TestFixture]
public class TaskRepositoryFixture
{
private ISessionFactory _sessionFactory;
private Configuration _configuration;
private readonly Task[] _tasks = new[]
{
new Task {Id = 1, Status = 1, Locked = 0, Library = new TaskLibrary { Id =1, Description = "Test Library", Name = "Tast.dll", Type = "RunnableTask", Dll = Encoding.ASCII.GetBytes("test binary data")}},
new Task {Id = 2, Status = 1, Locked = 0, Library = new TaskLibrary { Id =1, Description = "Test Library", Name = "Tast.dll", Type = "RunnableTask", Dll = Encoding.ASCII.GetBytes("test binary data")}},
new Task {Id = 3, Status = 1, Locked = 0, Library = new TaskLibrary { Id =2, Description = "Test Library 2", Name = "Tast2.dll", Type = "RunnableTask", Dll = Encoding.ASCII.GetBytes("test binary data")}},
new Task {Id = 4, Status = 1, Locked = 0, Library = new TaskLibrary { Id =2, Description = "Test Library 2", Name = "Tast2.dll", Type = "RunnableTask", Dll = Encoding.ASCII.GetBytes("test binary data")}},
new Task {Id = 5, Status = 1, Locked = 0, Library = new TaskLibrary { Id =3, Description = "Test Library 3", Name = "Tast3.dll", Type = "RunnableTask", Dll = Encoding.ASCII.GetBytes("test binary data")}},
};
private readonly TaskLibrary[] _libraries = new[]
{
new TaskLibrary { Id =1, Description = "Test Library", Name = "Tast.dll", Type = "RunnableTask", BinaryDll = Encoding.ASCII.GetBytes("test binary data")},
new TaskLibrary { Id =2, Description = "Test Library 2", Name = "Tast2.dll", Type = "RunnableTask", BinaryDll = Encoding.ASCII.GetBytes("test binary data")},
new TaskLibrary { Id =3, Description = "Test Library 3", Name = "Tast3.dll", Type = "RunnableTask", BinaryDll = Encoding.ASCII.GetBytes("test binary data")}
};
private void CreateInitialData()
{
using (ISession session = _sessionFactory.OpenSession())
using (ITransaction transaction = session.BeginTransaction())
{
foreach (var lib in _libraries)
session.Save(lib);
foreach (var task in _tasks)
session.Save(task);
transaction.Commit();
}
}
[TestFixtureSetUp]
public void TestFixtureSetUp()
{
_configuration = new Configuration();
_configuration.Configure();
_configuration.AddAssembly("DistPollAutoTasksShared");
_sessionFactory = _configuration.BuildSessionFactory();
}
[SetUp]
public void SetupContext()
{
new SchemaExport(_configuration).Execute(false, true, false, false);
CreateInitialData();
}
[Test]
public void CanGetLibraryFromTask()
{
ITaskRepository repository = new TaskRepository();
var fromDb = repository.GetById(_tasks[0].Id);
Assert.IsNotNull(fromDb.Library);
Assert.IsNotNull(fromDb.Library.Dll);
}
}
而且,任務表中MSSQL2000數據庫是這樣的:
CREATE TABLE [dbo].[Tasks](
[TaskId] [int] IDENTITY(1,1) NOT NULL,
[TaskLibrary] [int] NOT NULL,
[Status] [int] NOT NULL,
[Locked] [int] NOT NULL
)
如果你還在我身邊...
從我的Task類中,我只想爲Library屬性的TaskLibrary類的實例。另外,如果我正在使用庫本身,我希望能夠懶惰地檢索使用該庫的所有任務的IEnumerable。然而,當我運行測試時,我得到這個錯誤:
TestCase 'DistPollAutoTasksShared.Tests.TaskRepositoryFixture.CanGetLibraryFromTask'
failed: NHibernate.LazyInitializationException : Could not initialize proxy - no Session.
at NHibernate.Proxy.AbstractLazyInitializer.Initialize()
at NHibernate.Proxy.AbstractLazyInitializer.GetImplementation()
at NHibernate.Proxy.Poco.Castle.CastleLazyInitializer.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at TaskLibraryProxy2bd44073e90f47298039abfbfda11492.get_Dll()
這是我第一次使用NHibernate,所以我仍然在學習。我真的想要獲得基礎知識的良好基礎,所以我一直待在這裏。任何幫助,建議,閱讀材料(我讀過所有this question's建議和其他一些),將不勝感激。
編輯:
變化取=「加入」後,我發現了我從Task類想要的功能。不過,我添加了另一個測試爲TaskLibrary類的任務屬性:
[Test]
public void CanGetTasksByLibrary()
{
ITaskLibraryRepository repository = new TaskLibraryRepository();
var fromDb = repository.GetById(_libraries[0].Id).Tasks;
Assert.IsNotNull(fromDb);
Assert.True(fromDb.Count() == 2, "Cannot get IEnumerable<Task> from TaskLibrary");
}
但是,斷言失敗,此錯誤(我已經更新上面的代碼,以反映我所做的更改):
TestCase 'DistPollAutoTasksShared.Tests.TaskLibraryRepositoryFixture.CanGetTasksByLibrary'
failed:
Cannot get IEnumerable<Tasks> from TaskLibrary
Expected: True
But was: False
這是因爲您只能在會話打開時進行延遲加載。你不會急於加載TaskLibrary.Tasks,因爲這可能會以遞歸的方式發出大量的select語句。 – dotjoe 2009-08-20 16:49:35
@dotjoe,對。這就是爲什麼我設置了lazy =「true」,但它仍然拋出異常。所以,我不知道延遲加載是如何工作的。 – scottm 2009-08-20 16:55:09
基本上,延遲加載通過擴展您的poco(使用虛擬屬性)並在您嘗試使用它加載的會話時訪問其中一個屬性。如果會話關閉,您會收到錯誤消息。因此,在您嘗試訪問任務之前,會話已打開並關閉。 – dotjoe 2009-08-20 17:02:53