0

У меня есть bean-компонент в моем приложенииContext-test.xml, который я использую для издевательского поиска внешней поисковой системы. Таким образом, когда я запускаю тесты, каждый раз, когда код приложения ссылается на эту поисковую систему, я знаю, что я использую свой макетный движок вместо реального.Как повторно инициализировать мой фасоль

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

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

Одна из альтернатив, которую я рассматривал, состояла в том, чтобы полностью переинициализировать компонент. Компонент инициализируется из applicationContext-test.xml со статическим заводским методом. То, что я хочу сделать, это:

  1. Ссылка боб от моего тестового кода, чтобы изменить некоторые из своих шлейфов
  2. Выполните тест с использованием этих новых заглушек
  3. В конце этого испытания, переинициализировать боб с использованием статический фабричный метод, указанный в ApplicationContext-test.xml

Я пытался что-то вроде этого:

ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(
      new String[] { "applicationContext-test.xml" }); 
    Factory factory = appContext.getBean(Factory.class); 
    factory = EngineMocks.createMockEngineFactory(); 

Но это не делает трюк. Любые тесты, которые запускаются после этого, будут по-прежнему терпеть неудачу. Кажется, что моя новая переменная factory содержит , которую я хочу и ведет соответственно, но когда бит упоминается в другом месте, getDocuments() по-прежнему выдает исключение, которое было зашито ранее. Ясно, что моя повторная инициализация затронула только локальную переменную, а не сам компонент.

Может ли кто-нибудь сказать мне, как я могу выполнить свою цель?

Update

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

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

+0

Мой ответ будет зависеть от того, как вы в настоящее время создаете двойные тесты (например, mocks, stubs)? Это ручная работа или вы используете что-то вроде easymock или mockito? – 2010-12-07 18:30:25

+0

Мои mocks создаются с использованием Mockito, и они настраиваются через applicationContext. Другими словами, я не делаю mocks для каждого теста, который я пишу, но, скорее, код приложения ссылается на @Resource, поэтому, когда я запускаю тесты, я загружаю свой контекст приложения и каждый фрагмент кода приложения, который ссылается этот компонент теперь использует измененную версию вместо реальной. – Samo 2010-12-07 18:32:47

ответ

1

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

+0

Я не уверен, что вы имеете в виду. Это действительно два разных тестовых примера, но код приложения, к которому они обращаются, использует одно и то же определение компонента для моей фабрики. Я не хочу вручную вводить этот компонент через длинную цепочку сеттеров. – Samo 2010-12-06 22:06:12

0

Как насчет внедрения различных реализаций поисковой системы? Просто создайте больше бобов, представляющих разные макеты поисковой системы.

  • один тестовый класс инициализируется одним макетным и другим классом испытаний с другим манекеном; это, конечно, означает, что вы будете иметь больше тестовые классы для определенного класса, что вы тестируете (не то, что хороший/чистый)

или ...

  • впрыснуть больше издевается (из поисковая система) в 1 классе тестирования. некоторые методы испытаний (от этого тестирования класса) используют один макет, другие методы тестирования использовать другой макет
0

Вместо:

factory = EngineMocks.createMockEngineFactory(); 

сделать:

factory.callMethodThatChangesTheStateOfThisObjectSuchThatItIsSuitableForYourTest(withOptionalParameters); 

Кроме того, если вы используете Spring Integration Testing, обязательно отметьте свой метод с помощью @DirtiesContext, чтобы он не повлиял на следующий тест.