Можно ли использовать методы модульного тестирования, использующие NHibernate Detached Criteria? - PullRequest
1 голос
/ 11 июня 2010

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

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

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

Класс репозитория

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>();
    }
*

} * 1013

Примечание. Здесь я также использую "NHibernate.LambdaExtensions" и "Castle.Facilities.NHibernateIntegration". Буду признателен за любую помощь.

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

Ответы [ 2 ]

5 голосов
/ 11 июня 2010

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

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

1 голос
/ 11 июня 2010

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

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

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

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

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

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

...