1

Я попытался использовать Moq для тестирования метода в репозитории, который использует класс DetachedCriteria. Но я сталкиваюсь с проблемой, из-за которой я не могу фактически издеваться над внутренним объектом Criteria, который встроен внутри. Есть ли способ издеваться над отдельными критериями?Можно ли использовать единые методы тестирования, которые зависят от отдельных критериев NHibernate?

Метод испытания

 [Test] 
     [Category("UnitTest")] 
     public void FindByNameSuccessTest() 
     {   
      //Mock hibernate here 
      var sessionMock = new Mock<ISession>(); 
      var sessionManager = new Mock<ISessionManager>(); 
      var queryMock = new Mock<IQuery>(); 
      var criteria = new Mock<ICriteria>(); 
      var sessionIMock = new Mock<NHibernate.Engine.ISessionImplementor>(); 

      var expectedRestriction = new Restriction {Id = 1, Name="Test"}; 

      //Set up expected returns 
      sessionManager.Setup(m => m.OpenSession()).Returns(sessionMock.Object); 
      sessionMock.Setup(x => x.GetSessionImplementation()).Returns(sessionIMock.Object); 

      queryMock.Setup(x => x.UniqueResult<SopRestriction>()).Returns(expectedRestriction); 

      criteria.Setup(x => x.UniqueResult()).Returns(expectedRestriction); 

      //Build repository    
      var rep = new TestRepository(sessionManager.Object); 

      //Call repostitory here to get list 
      var returnR = rep.FindByName("Test"); 


      Assert.That(returnR.Id == expectedRestriction.Id); 
     } 

Repository Класс

public class TestRepository 
{ 
    protected readonly ISessionManager SessionManager; 

    public virtual ISession Session 
    { 
     get { return SessionManager.OpenSession(); } 
    } 

    public TestRepository(ISessionManager sessionManager) 
    { 
    } 


    public SopRestriction FindByName(string name) 
    { 

     var criteria = DetachedCriteria.For<Restriction>().Add<Restriction>(x => x.Name == name) 
     return criteria.GetExecutableCriteria(Session).UniqueResult<T>(); 
    } 

}

Примечание Я использую "NHibernate.LambdaExtensions" и "Castle.Facilities.NHibernateIntegration" здесь, как Что ж. Любая помощь будет с благодарностью оценена.

По сути, я получаю исключение с ссылкой на null для утверждения возвращаемого объекта. Таким образом, я предполагаю, что я не правильно подключил критерии. Но я не думаю, что могу это сделать, потому что критерии - это частное поле Частных критериев, которое создается внутри моего репозитория!

ответ

5

Честно говоря, я отказался от попыток модульного тестирования всего, что касается базы данных давным-давно.

Гораздо проще развернуть память Sqlite db и просто запустить фактические тесты. Или, если вы предпочитаете запускать их против реальной базы данных, а затем просто переместите их в свои интеграционные тесты, которые будут выполняться только тогда, когда вы проверите контроль источника.

+0

Я не говорю о касании базы данных. Я тестирую классы репозитория. Убедившись, что они действительно получают доступ к правильным методам. Я сопоставляю тесты отдельно с Sqlite. Я думаю, вы неправильно поняли мой вопрос. Я издевался над nhibernate, не тестируя фактическую базу данных. –

+0

Я согласен с тем, что вы говорите, но это не ответ на вопрос. –

+0

Но зачем издеваться над NHibernate? Почему бы просто не попасть в реальную базу данных?Вы должны быть осторожны в том, чтобы слишком сосредоточиться на том, как что-то делается, что приводит к запахам над тестирующими характеристиками. Что вы должны волноваться, так это получить ожидаемые результаты, когда я использую свой репозиторий. –

1

Я думаю, что вам не хватает смысла использовать насмешку над этим ситутацией. То, что вы хотите, чтобы дразнить метод

public SopRestriction FindByName(string name) 
{ 
    ... 
} 

Итак вы можете вернуть любой тип SopRestriction вы хотите и не беспокоиться о том, что это NHibernate поиска информации.

Бессмысленно когда-либо издеваться над любым типом данных, потому что вы никогда не получите никакой ценности.

Самый простой способ сделать это - извлечь интерфейс из TestRepository, так же как и ITestRepository, а затем сделать остальную часть графика зависимостей зависимым от ITestRepository, и вы можете легко издеваться над репозиторием в своих модульных тестах.

Развейте: Что касается вашего ответа о желании проверить вызовы методов внутри вашего хранилища, что я рекомендовал бы оборачивает все конкретного использования NHibernate в самих методах, которые не имеют какой-либо тип параметра или возврата, NHibernate поэтому вы можете издеваться над этими методами и просто ожидать, что они будут работать. Вот почему модульное тестирование на данном этапе менее ценно, потому что вы мало выигрываете. С тем, что вы сказали, я бы вообще не высмеял их, но сделал бы их полные «интеграционные» тесты, которые касаются базы данных или делают то, что им нужно делать. Я все еще рассматриваю их как единичные тесты, даже если пуристы TDD скажут, что они являются интеграционными тестами.

+0

Конечно, я могу издеваться над сервисом или другим шаблоном, который обладает свойством, которое создает экземпляр ITestRepository. Однако я хочу протестировать SopRepository, чтобы узнать, были ли вызваны определенные методы, чтобы не получать значение. Поэтому я думаю, что вы также отвечаете на другой вопрос. –