2014-05-20 39 views
5

我试图用TDD让自己的双脚变得湿润。我正在尝试为使用Mockito和MockMvc和Junit的控制器编写单元测试用例。java.lang.NoSuchMethodError:javax.servlet.http.HttpServletRequest.isAsyncStarted()与Junit一起使用Mockito

但我得到一个运行时错误,从而失败我的测试。起初,由于找不到javax.servlet.SessionCookieConfig,我在初始化设置中的MockMvc实例时遇到了问题。

这是我通过下载javax.servlet API和它配置到项目的构建路径,但然后我一会儿就MockMvc实例使用perform()面临的

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

解决。

任何人都可以告诉我如何处理这种依赖关系,因为我认为这是由于服务器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; 
    } 
} 

回答

7

这听起来很像你打错类路径中的servlet API版本。

检查何时将isAsyncStarted添加到API中,并确保您在类路径中引用的那个至少是该版本或更高版本。

为了找到其中的“错误”类的版本从正在添加,你可以使用

-verbose:class 

参数为Java的位置。它会列出所有加载的类,并且如果我没有记错它们从中加载。详情请参阅http://docs.oracle.com/javase/7/docs/technotes/tools/windows/java.html

+0

嗨延斯 我检查了API isAsyncStarted已添加到servlet 3.0中,我在我的项目构建中使用java.servlet-3.0.jar。 – Sourabh

+0

这就是发展。检查服务器是否使用相同的servlet api级别。 –

+0

服务器具有相同的servlet api级别。 – Sourabh

1

当您的开发和生产环境使用不同的servlet API版本时,会发生这种情况。

使用tomcat7(例如)构建时,它支持servlet 3,因此您不会收到任何错误。

虽然在较低版本的tomcat上做同样的事情,它会抛出错误。

解决方案

要么升级的环境之一,支持servlet的3或只是降级代码中使用的servlet 2.5

+0

嗨Manish,我想到了相同但惊人的我一直在使用apache tomcat 7.0.40和javax.servlet-3.0.jar。我不能将javax servlet降级到2.5,因为它不包含SessionCookieConfig类。所以升级tomcat将是一个选择,但它已经在兼容版本。 – Sourabh

0

我发现我的错误的解决方案。实际提供的servlet api是gwt-servlet.jar,而gwt-servlet.jar中的servlet-api是旧版本的。因此,我配置了我的构建路径,以便在构建过程中使项目指向最新的servlet-api。

至于正确的答案,我认为我的投票去了Jens,因为他确实给出了最接近每个场景的解决方案。

谢谢大家。 :)

+0

谢谢。它适用于servlet-api.jar 3.0.1,没有任何问题。 – rakeeee

1

错误消息表明您的类路径中有错误版本的Servlet API。

如果您正在使用的摇篮执行

gradle dependencies 

分析依赖关系树,并与版本低于3.0排除“的servlet-API”的依赖。您可以执行以下操作以排除

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

可能存在多个依赖关系,这些依赖关系还包括servlet-api-2.x。排除那些

+0

谢谢,这是我的案子的解决方案。 org.apache:storm-core使用servlet-api 2.5,但是io.confluent:kafka-schema-registry使用servlet-api 3.1。我必须排除风暴中的依赖关系才能使我的代码正常工作。 – asmaier

0

我加入到Java构建路径Tomcat作为服务器运行时库

mockito javax.servlet.SessionCookieConfig problem

0

我有我的JUnit测试的类似问题的一些不工作(在IntelliJ IDEA的)解决了这个问题对于这些单元测试,我也得到了java.lang.NoSuchMethodError: javax.servlet.http.HttpServletRequest....。当我尝试使用命令gradle clean build通过命令提示符从目录中使用gradle编译完整项目时,代码正在编译成功。然而问题是在Intellij思想中的Junit测试中,他们显示了上述错误。我只是将我的gradle版本从3.4.1更改为2.1.3。我不知道为什么现在我的Junit测试正在编译以及我的代码正在通过intellij以及通过命令提示符进行编译。同样的问题发生在我的另一位同事身上,他也将gradle版本从4改为2的某个版本。问题解决了。