Зачем мне использовать MockRunner вместо обычного / ручного внедрения зависимостей? - PullRequest
0 голосов
/ 03 августа 2010

В нашей компании у нас есть сервисный уровень, который принимает некоторый XML-запрос, обращается к различным хранимым процедурам (SP) через JDBC, обрабатывает данные и отвечает некоторым ответным XML.В последнее время люди начали использовать MockRunner в своих тестах JUnit, чтобы высмеивать ответы от SP.Код для настройки ложных ответов от SP, использующий MockRunner, выглядит ужасно (это первый случайный тестовый класс, который я открыл):

    MockConnection connection = new MockConnection();
    MockContextFactory.setAsInitial();
    InitialContext context = new InitialContext();
    context.rebind(READ_PAYMENT_DATA_SOURCE, getDS());
    getDS().setupConnection(connection);
    m_csStatementHandler = connection.getCallableStatementResultSetHandler();
    m_csStatementHandler.clearResultSets();
    m_csStatementHandler.clearCallableStatements();
    m_csStatementHandler.setExactMatch(false);
 m_csStatementHandler.prepareReturnsResultSet(READ_PAYMENT, true);
    m_csStatementHandler.setExactMatch(false);
    m_csStatementHandler.setExactMatchParameter(false);
    Map parameterMap = new HashMap();
    parameterMap.put(new Integer(1), null);
    parameterMap.put(new Integer(2), null);
    parameterMap.put(new Integer(3), null);
    parameterMap.put(new Integer(4), null);
    m_csStatementHandler.prepareOutParameter(READ_PAYMENT, parameterMap);
    //Set up the cursor of applications for return.
    MockResultSet resultApps = m_csStatementHandler.createResultSet();  

    resultApps.addRow(getPaymentSchedule("E", "Monthly", new Short("1"),null,null,null,null,null,null,null));
    resultApps.addRow(getPaymentSchedule("A", "Weekly", new Short("1"),null,null,null,null,null,null,null));
    resultApps.addRow(getPaymentSchedule("R", "Yearly", new Short("1"),null,null,null,null,null,null,null));
    resultApps.addRow(getPaymentSchedule("S", "Weekly", new Short("1"),null,null,null,null,null,null,null));
    resultApps.addRow(getPaymentSchedule("W", "Monthly", new Short("1"),null,null,null,null,null,null,null));

    MockResultSet[] results = new MockResultSet[1];
    results[0] = resultApps;
    m_csStatementHandler.prepareResultSet(READ_PAYMENT, resultApps);   

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

До настоящего времени я использовал инъекцию зависимостей, введенную вручную, чтобы внедрить класс, который фактически вызывает хранимую процедуру.Все, что мне нужно сделать, это создать фиктивный класс вызывающего SP (ответственный за фактическое выполнение SP) и установить желаемые данные ответа.Я очень доволен этой техникой, и она намного проще, чем описанная выше, поскольку она ориентирована на данные, а не беспокоится о деталях реализации.Но мой вопрос: когда вы захотите использовать MockRunner?Это кажется излишним для модульных тестов, так что я предполагаю, что это больше для интеграции или тестирования системы?И даже тогда мне все еще кажется, что проще использовать инфраструктуру DI для замены класса вызывающего SP, а затем настраивать весь код выше для каждого вызова хранимой процедуры.Пожалуйста, просветите!Спасибо

1 Ответ

3 голосов
/ 04 августа 2010

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

Сообщество по тестированию / издевательствам часто проводит различие между тем, что вы катите вручную, что обычно называется «заглушкой» (статический рукописный класс), и «макетом» (динамический класс, генерируемый во время выполнения) .

Преимущества насмешек довольно велики по сравнению с простой заглушкой. Многие тестировщики недовольны идеей переписать реализации интерфейсов и / или конкретных классов подклассов только для целей тестирования. Для этого часто требуется реализация ВСЕХ методов указанного класса / интерфейса, даже если вы просто хотите протестировать определенный метод.

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

Синтаксис немного варьируется от насмешливой библиотеки к библиотеке. Некоторые вы можете найти более читабельными, чем другие. Мой нынешний фаворит - Mockito, отсюда и более ранние ссылки, но они развиваются со временем. Возможно, стоит выяснить, почему ваша организация использует набор инструментов для пересмотра и может ли другая по-прежнему отвечать вашим потребностям, а также быть более читабельной.

Надеюсь, ваши авторы тестов применяют обычное поведение в методах настройки тестов (например, JUnit's @Before), поэтому вам не нужно постоянно видеть создание макетов и общую инициализацию повсюду.

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