我有AddBookController
:
public class BookAddController extends HttpServlet {
@EJB(name = "BuyerServiceEJB")
private BuyerServiceInterface buyerService;
@EJB(name = "AuthorServiceEJB")
private AuthorServiceInterface authorService;
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Book newBook = new Book();
newBook.setName(request.getParameter("name"));
newBook.setAuthor(authorService.findAuthorById(Long.parseLong(request.getParameter("author_id"))));
newBook.setBought(Boolean.parseBoolean(request.getParameter("sold")));
newBook.setGenre(request.getParameter("genre"));
newBook.setPrice(Integer.parseInt(request.getParameter("price")));
buyerService.addNewBook(newBook);
doGet(request, response);
}
我有测试课:
public class BookAddControllerTest {
final static Logger logger = Logger.getLogger(UserServiceBean.class);
private Book testBook = new Book();
private Author testAuthor = new Author();
@Before
public void precondition(){
logger.info("Add Book Controller Test");
testBook.setName("Возера Радасці");
testAuthor.setAuthor_id(1L);
testBook.setAuthor(testAuthor);
testBook.setBought(false);
testBook.setGenre("postmodernism");
testBook.setPrice(15);
}
@Test
public void testDoPost() {
logger.info("Test post request processing");
BookAddController bookAddController = Mockito.mock(BookAddController.class);
HttpServletRequest testRequest = Mockito.mock(HttpServletRequest.class);
HttpServletResponse testResponse = Mockito.mock(HttpServletResponse.class);
BuyerServiceInterface buyerServiceInterface = Mockito.mock(BuyerServiceInterface.class);
AuthorServiceInterface authorServiceInterface = Mockito.mock(AuthorServiceInterface.class);
when(testRequest.getParameter("name")).thenReturn("Возера Радасці");
when(testRequest.getParameter("author_id")).thenReturn("1");
when(testRequest.getParameter("sold")).thenReturn("false");
when(testRequest.getParameter("genre")).thenReturn("postmodernism");
when(testRequest.getParameter("price")).thenReturn("15");
bookAddController.doPost(testRequest, testResponse);
verify(buyerServiceInterface, times(1)).addNewBook(testBook);
verify(authorServiceInterface, times(1)).findAuthorById(Long.parseLong("1"));
verify(bookAddController, times(1)).doGet(testRequest, testResponse);
}
我收到例外:
java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/servlet/ServletException
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
at java.lang.Class.getMethod0(Class.java:3018)
at java.lang.Class.getMethod(Class.java:1784)
at org.junit.internal.builders.SuiteMethodBuilder.hasSuiteMethod(SuiteMethodBuilder.java:18)
at org.junit.internal.builders.SuiteMethodBuilder.runnerForClass(SuiteMethodBuilder.java:10)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:33)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:98)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
问题:
doPost
方法?答案 0 :(得分:3)
由于用户@SMA意味着你实际上没有测试任何东西,因为你只是在模拟代码上运行。您要做的是创建BookAddController
的实例,并在您致电HttpServletRequest
时传递HttpServletResponse
和doPost
的模拟实例。否则,您不会使用您编写的任何代码,因此您无法知道您编写的实际代码是否有效或是否发生任何回归。
至于异常,我怀疑junit
可能无法访问java ee api。在您的pom中包含javaEE,它可能会起作用。请查看此question了解详情
答案 1 :(得分:2)
这是一个令人兴奋的问题,因为Oracle没有为许多类提供方法体 - 所有你得到的就是API,这使得无法实际使用JAR文件来运行任何东西。有关详情,请参阅此JBoss Wiki article:
这个问题可能是你的测试类路径上有javax:javeee-api(或javax:javaee-web-api)库的结果。如果您有Maven项目,则可能在POM文件中具有以下依赖项:
<dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>6.0</version> </dependency>
或者:
<dependency> <groupId>javax</groupId> <artifactId>javaee-web-api</artifactId> <version>6.0</version> </dependency>
此依赖项为您提供Java EE API,而不是实现。虽然此依赖项适用于编译,但它不能用于执行代码(包括测试)。
背景
当这些工件发布到Maven存储库时,Sun / Oracle从类别&#34;实现&#34;中删除了代码。所以所有接口都是代码完整的,但是任何抽象类或实现类都没有代码。任何使用该类的尝试都可能会爆炸。
以下是关于Sun / Oracle为何这样做的论点的摘录:
当编译时,他们也希望运行。顺便说一句,我们一直在推广只能用于编译的全套Java EE API - 它们被剥离了方法细节。这样,用户就无法获取这些工件并尝试在运行时使用它。
基本上,javax:javaee-api和javax:javaee-web-api Maven工件并不是真正的交易 - 它们是“存根”。它们非常适合轻松提供编译所需的依赖项,但是当您需要执行某些操作时它们会完全断开。
解决方法:不要使用javax.javaee-api或javax:javaee-web-api工件!相反,使用&#34; real&#34;你需要的文物。遗憾的是,没有Maven作用域可以从测试类路径中排除依赖项(尽管在surefire插件中有一个classpathDependencyExcludes配置选项,用于在测试期间将它们列入黑名单)。
解决方法是使用以下内容:
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-servlet_3.0_spec</artifactId>
<version>1.0</version>
<scope>test</scope>
</dependency>
或JBoss版本,或包含您正在使用的类的实际实现的其他版本。