Как заставить мой тестовый запуск Eclipse JUnit вести себя так же, как и запуск теста в командной строке mvn?
Я использую Eclipse Juno на Mac 10.9.1, Maven 3.1.1, JUnit 4.11, и у меня есть зависимость Apache httpcomponents:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.4</version>
</dependency>
Когда я запускаю тест JUnit в Eclipse (щелкнув правой кнопкой мыши по имени моего теста и выбрав "Run As" -> "Junit Test"), я получаю следующую ошибку
java.lang.NoSuchMethodError: org.apache.http.impl.client.DefaultHttpClient.execute(Lorg/apache/http/client/methods/HttpUriRequest;)Lorg/apache/http/client/methods/CloseableHttpResponse;
at org.usersubscr.subco.ebook.mvc.CleverInstantLoginController.validateInstantAccessLogin(CleverInstantLoginController.java:143)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:100)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:604)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:565)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.mainco.subco.ebook.mvc.CleverInstantLoginControllerTest.submitLoginWithCode(CleverInstantLoginControllerTest.java:119)
at org.mainco.subco.ebook.mvc.CleverInstantLoginControllerTest.testInstantLoginSuccess(CleverInstantLoginControllerTest.java:105)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Конкретная линия, где вещи умирают,
response1 = httpclient.execute(httppost);
Огорчает то, что когда я запускаю тот же тест в командной строке, используя
mvn clean test -Dtest=MyHttpTest
Тест работает без ошибок. Я попытался запустить "mvn eclipse:eclipse" в моем проекте и обновить рабочее пространство, но это, похоже, не помогает. Как я могу заставить Eclipse JUnit вести себя так же, как при выполнении теста в командной строке?
2 ответа
Хорошо, была такая же проблема с
java.lang.NoSuchMethodError: org.apache.commons.collections.MapUtils.isNotEmpty
Для меня это было потому, что Hibernate включает в себя commons-collection-3.1, который не включает метод isNotEmpty(). Я думал, что это было действительно странно, поскольку, когда я использовал функцию иерархии зависимостей плагина m2e, он показал мне, что автоматически исключает зависимость и использует вместо нее 3.2. Что еще хуже, казалось, что ручное исключение артефакта из помпа ничего не делало.
Для меня проблема заключалась в том, что у меня была зависимость Maven с установленной для проверки областью действия, и по какой-то причине Eclipse JUnit использовал эту зависимость без исключения. У меня есть многомодульный проект, и я пытался выяснить проблему в последующем модуле (то есть я искал иерархию зависимостей модуля, который включал модуль, который включал другой модуль, который имел зависимость, которая вызывала проблемы), поэтому Плагин Eclipse Maven не видел зависимости, поскольку тестировалась область. Как уже было сказано, JUnit не понимает, что не следует использовать эту зависимость в дальнейшем, и это доставило мне головную боль.
Для вас проблема может быть чем-то другим, поэтому я стараюсь дать более общую картину, чтобы отследить проблему. Ниже описан процесс, который я использовал для отслеживания и устранения проблемы, надеюсь, это поможет:
- использовал плагин m2e Dependency Hierarchy для отслеживания всех версий зависимости
- обнаружил, что Hibernate использует старую зависимость
- пошел в мой локальный репо м2 и переименовал все неправильные версии (см. изображение)
- запустить тесты (чтобы убедиться, что мы на правильном пути), они должны потерпеть неудачу, говоря, что зависимость не может быть найдена
- используйте Notepad++, чтобы найти все файлы, которые содержат неправильную зависимость (для меня строка поиска была "commons-collection /3.1/commons-collection-3.1.jar", а фильтр имен файлов был ".classpath")
- узнать модули, пытающиеся его использовать
проверьте точные файлы pom и исключите виновника (для меня это было следующим:)
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-annotations</artifactId> <version>3.5.6-Final</version> <scope>test</scope> <exclusions> <exclusion> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> </exclusion> </exclusions> </dependency>
Я часто сталкиваюсь с этой проблемой.
Если я бегу из Maven, из командной строки или из Eclipse, то я всегда делаю mvn clean test
,
Если я работаю как JUnit из Eclipse, то сначала я делаю Project > Clean (затем сборка) и, наконец, запускаю как JUnit. Если это по-прежнему не решает проблему, я сначала делаю Maven Clean и повторяю процедуру.
Суть в том, что у Maven и Eclipse есть свое (сильное) мнение о том, как устроен мир, и в некоторых случаях они противоречат друг другу.