Перемешивание вызовов .nettiers DataRepository - PullRequest
0 голосов
/ 05 декабря 2011

У меня есть проект, в котором я использую сгенерированный код .nettiers в качестве моего DAL.

В настоящее время мои тесты состоят из физической настройки тестовых данных в базе данных для каждого теста, а затем разрешения объектам nettiers попадать в базу данных и возвращаться по мере необходимости.

Очевидно, что это не особенно эффективно, и до сих пор мои 250 с лишним тестов занимали около 10 минут, поэтому я пытался добавить в мои тесты насмешку.

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

Один из методов, которые я хочу протестировать, выглядит следующим образом (для краткости немного сокращен):

public class InterfaceManagerService
{
    public DataDocument SaveDataDocument(DataDocument entity)
    {
        var lookupEntity = DataRepository.DataDocumentProvider.GetByDocumentId(entity.DocumentId);
        if (lookupEntity == null)
        {
            File fileEntity = new File();
            fileEntity.Name = entity.Name;

            var savedFileEntity = DataRepository.FileProvider.Save(fileEntity);

            entity.FileId = savedFileEntity.FileId;

            var savedEntity = DataRepository.DataDocumentProvider.Save(entity);

            return (savedEntity);
        }             
    }
}

В настоящее время я использую пробную версию Typemock, так как она, кажется, делает то, что требуется, но я открыта для любых альтернатив, особенно с открытым исходным кодом.

Первая проблема, с которой я столкнулся, заключалась в том, что мне нужно было создать поддельный экземпляр InterfaceManagerService, или DataRepository, или самих сущностей (у сущностей нетто есть интерфейс, который может быть полезен).

Вторая проблема заключается в том, как создать поддельный объект, который должен быть возвращен, поскольку nettiers помещает кучу дополнительных свойств в сущности, что приведет к большим и громоздким тестам, если я создам поддельный экземпляр каждого объекта I ' м ожидаю.

Полагаю, в конечном счете, я ищу какое-то направление, чтобы наилучшим образом написать модульные тесты для методов, использующих методы хранилища данных nettiers, но чтобы избежать попадания в базу данных, поскольку, похоже, об этом много не говорится. Интернет в настоящее время.

Ответы [ 2 ]

3 голосов
/ 05 декабря 2011

Я собираюсь дать некоторые предложения, основанные на моем личном опыте.Хотя они могут не решить все ваши проблемы, я надеюсь, что они, по крайней мере, окажут вам некоторую помощь.

  • Rhino Mocks - довольно известная среда для насмешек.Если вы ищете альтернативу Typemock, я бы предложил.

  • Что касается насмешки над InterfaceManagerService или DataRepository, я бы сказал, что это зависит от того, что выпытаюсь проверить.Хотите протестировать InterfaceManagerService?Затем вы захотите создать фиктивные объекты для DataRepository.FileProvider и DataRepository.DataDocumentProvider.Если вы еще не знакомы с понятием «внедрение зависимости», посмотрите на это;похоже, вам следует применить какое-то внедрение зависимостей к вашему классу InterfaceManagerService (при условии, что вы хотите выполнить его модульное тестирование).

    Если вы хотите выполнить код модульного тестирования, который использует InterfaceManagerService, просто смоделируйте InterfaceManagerService.

... как создать поддельный объект, который должен быть возвращен, так как nettiers помещает кучу дополнительных свойств в сущности, что приведет к большим и громоздким тестам, если я создамподдельный экземпляр каждого объекта, который я ожидаю.

  • Написание одиночного модульного теста легко.Написание многих модульных тестов для охвата всех сценариев, которые вам необходимо охватить, и эффективное выполнение этого, которое не приводит к дублированию большого количества кода во время ваших модульных тестов, особенно когда входные и выходные данные тестируемого методаявляются сложными.

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

    В общем, я думаю, что в итоге я разделил логику тестирования на 3 категории: входные данные/ инициализация, ожидания и результаты / проверка.Я обнаружил, что объединение логики в эти 3 категории помогло мне консолидировать общий код в модульных тестах.

    Сторонники разработки, основанной на жестких тестах, вероятно, скажут, что пытаются создатьЧистый набор кода модульного тестирования является признаком конструктивного изъяна в приложении.Я не собираюсь с этим не согласиться, но скажу, что, к сожалению, проекты, в которых я принимал участие, обычно не создавали кодовую базу модульного тестирования, которая была бы простой и полностью всеобъемлющей.Простые модульные тесты обычно не исследовали проблемные сценарии, а комплексные модульные тесты обычно требовали большой логики настройки теста.

0 голосов
/ 05 декабря 2011

Я использую TypeMock, и мне это очень нравится. Это действительно легко издеваться над внутренностями класса. Я пытаюсь переопределить класс DataRepository и заставить TypeMock вернуть ожидаемый набор результатов моему компоненту, который его потребляет, чтобы убедиться, что компонент работает должным образом.

Но на самом деле это зависит от того, что вы тестируете. Если вы тестируете сервис, подделайте репозиторий данных и верните ожидаемые результаты. Если вы тестируете репозиторий, то имитируйте внутренние компоненты, которые использует репозиторий. Поэтому хорошей идеей является подделка внешних ссылок на компонент, который вы тестируете, ИМХО.

НТН.

...