Помогите мне протестировать отношения один-ко-многим с NHibernate и NUnit - PullRequest
1 голос
/ 20 августа 2009

У меня есть класс Task, и у него есть свойство TaskLibrary, из которого dll будет загружать и запускать некоторый код. Итак, любая задача имеет одну библиотеку, но любая библиотека может иметь много задач. Моя проблема в том, что мой тест для проверки того, что свойство Library задачи не равно null, не проходит (поэтому это может быть просто мой тест). Мои занятия по сути такие:

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 я просто хочу экземпляр класса TaskLibrary для свойства Library. Кроме того, если я работаю с самими библиотеками, я хочу иметь возможность лениво извлекать 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, так что я все еще учусь. Я действительно хочу получить хорошую основу основ, поэтому я застрял здесь до тех пор. Буду признателен за любую помощь, предложения, материалы для чтения (я прочитал все предложения этого вопроса и некоторые другие) и будет признателен.

EDIT:

После изменения fetch = "join" я получаю нужные мне функции из класса Task. Однако я добавил еще один тест для свойства Tasks класса 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

Ответы [ 3 ]

1 голос
/ 20 августа 2009
<many-to-one name="Library" class="TaskLibrary" fetch="join" />

Это будет присоединяться к библиотеке при каждом выборе.

<many-to-one name="Library" class="TaskLibrary" lazy="false" />

Это будет нетерпеливо выполнить отдельный выбор для библиотеки.

В противном случае загрузка библиотеки будет ленивой, если вы установите только fetch = "select" (по умолчанию).

http://ayende.com/Blog/archive/2009/04/09/nhibernate-mapping-ltmany-to-onegt.aspx

http://nhibernate.info/doc/nh/en/index.html#collections-lazy

0 голосов
/ 20 августа 2009

Не меняйте отображение для теста, ваши требования должны определять способ отображения объектов. Ваш метод репозитория закрывает сессию после извлечения из DB. Вы должны держать сеанс открытым для всего метода тестирования. Чтобы понять, как это сделать, вам нужно рассказать нам, как вы управляете своим сеансом. Связаны ли они с транзакцией / локальным потоком?

0 голосов
/ 20 августа 2009

вы пытались установить Lazy = "false" в вашем отображении? http://code -redefined.blogspot.com / 2007/07 / гибернации-отложенной выборки-проблемы-мог-not.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...