java.lang.NoSuchMethodError: javax.servlet.http.HttpServletRequest.isAsyncStarted() при использовании Mockito с Junit

Я пытаюсь промокнуть ногами от TDD. Я пытаюсь написать тестовые примеры для контроллеров, использующих Mockito в сочетании с MockMvc и Junit.

Но я получаю ошибку во время выполнения, в результате чего мой тест не пройден. Сначала я столкнулся с проблемой при инициализации экземпляра MockMvc в настройке из-за сбоя при поиске javax.servlet.SessionCookieConfig,

Это я решил, загрузив javax.servlet API и настройки его в пути сборки проекта, но потом я сталкиваюсь с

java.lang.NoSuchMethodError: javax.servlet.http.HttpServletRequest.isAsyncStarted()

при использовании perform() на экземпляре MockMvc.

Может кто-нибудь сказать мне, что делать с такого рода зависимостями, поскольку я думаю, что это происходит из-за несовместимого сервера servlet-api и javax.servlet api.

РЕДАКТИРОВАТЬ: я публикую код, который я использую для модульного тестирования, но я не думаю, что это поможет, но на всякий случай:

@RunWith(MockitoJUnitRunner.class)
public class MyControllerTest {

    @InjectMocks
    private MyController myController = new MyController();

    @Mock
    private MyService myService = new MyServiceImpl();

    private MockMvc mockMvc;

    @Before
    public void setUp(){
        this.mockMvc = MockMvcBuilders.standaloneSetup(myController).build();
    }

    @Test
    public void testList() throws Exception{
        A a = new A();
        a = createMockClassA();

        Mockito.when(myService.getServiceForA(Mockito.anyMapOf(String.class, String.class))).thenReturn(a);

        MvcResult result = this.mockMvc.perform(get("/somePath/")).param("someExpectedParam","value").andReturn(); 

        System.out.println(result.getResponse().getContentAsString());

    }



    private static A createMockClassA(){
        A a = new A();
        a.setId(i);
        a.setTitle("mock-" + i);
        return a;
    }
}

6 ответов

Решение

Это очень похоже на неправильную версию API сервлета в пути к классам.

Проверьте когда isAsyncStarted был добавлен в API и убедитесь, что тот, на который вы ссылаетесь в вашем class path, имеет по крайней мере ту версию или выше.

Чтобы найти место, откуда приходит "неправильная" версия класса, вы можете использовать

-verbose:class

Аргумент в пользу Java. В нем будут перечислены все загруженные классы, и если я правильно помню, откуда они загружаются. См. http://docs.oracle.com/javase/7/docs/technotes/tools/windows/java.html для получения подробной информации.

Это происходит, когда ваши среды разработки и производства используют разные версии API сервлетов.

При сборке с tomcat7(например) он поддерживает сервлет 3 и, следовательно, вы не получите никакой ошибки.

Делая то же самое на более низкой версии Tomcat, он выдаст ошибку.

Решение:

Либо обновите одну из сред для поддержки сервлета 3, либо просто понизьте код, чтобы использовать сервлет 2.5.

Сообщение об ошибке означает, что в вашем пути к классам установлена ​​неверная версия API сервлета.

Если вы используете Gradle, выполните

gradle dependencies

проанализируйте дерево зависимостей и исключите зависимости 'servlet-api' версии ниже 3.0. Вы можете сделать следующее, чтобы исключить

compile ('javax.servlet:jsp-api:2.0'){
    exclude module : 'servlet-api'
}

Может быть несколько зависимостей, которые дополнительно включают servlet-api-2.x. Исключить все

У меня была похожая проблема, некоторые из моих тестов Junit не работали (по идее intellij), и я также получал java.lang.NoSuchMethodError: javax.servlet.http.HttpServletRequest.... для этих юнит-тестов. Когда я пытаюсь скомпилировать весь проект, используя gradle, из каталога через командную строку с помощью команды gradle clean build тогда код был успешно скомпилирован. Принимая во внимание, что проблема была с тестами Junit в идее Intellij, они показывали вышеупомянутую ошибку. Я просто изменил свою версию Gradle с 3.4.1 на 2.1.3. Я не знаю, почему сейчас мои тесты Junit компилируются, а мой код компилируется как через intellij, так и через командную строку. Та же проблема возникла с другим моим коллегой, и он также изменил версию Gradle с 4 на какую-то версию 2. Проблема была решена.

Я нашел решение для моей ошибки. Фактический api сервлета, который был получен, был gwt-servlet.jar, а сервлет-api в gwt-servlet.jar был более старой версии. Таким образом, я сконфигурировал путь сборки, чтобы во время сборки проект указывал на последний сервлет-API.

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

Спасибо всем.:)

Я решаю эту проблему, добавляя в Java путь сборки Tomcat в качестве библиотеки времени выполнения сервера

mockito javax.servlet.SessionCookieConfig проблема

Другие вопросы по тегам