在 Maven WebApp 项目下使用嵌入式 Tomcat 7/junit 测试 RESTFul Spring 3 服务
目的是,对于每个单元测试,系统地启动 tomcat 7 服务器,加载 spring 应用程序(最终删除/创建模式并在数据库中初始化其数据)执行单元测试并停止 http 服务器。
使用jetty嵌入式服务器很容易找到示例来做到这一点,
我没有找到配置嵌入式tomcat 7服务器以加载spring上下文的正确方法
你能帮我吗?
项目结构是一个名为“myApp”的标准maven webApp项目,
src
+-main
+-java
+-webapp
+-static
+-WEB-INF
+-web.xml
+-applicationcontext.xml
target
+-myApp
+-webapp
+-static
+-WEB-INF
+-classes
抽象单元测试:
import org.junit.After;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.apache.catalina.Context;
import org.apache.catalina.core.AprLifecycleListener;
import org.apache.catalina.core.StandardServer;
import org.apache.catalina.startup.Tomcat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"applicationContext.xml"})
public abstract class AbstractMainHTTPTestCase
{
private int PORT;
private Tomcat tomcat;
private String appBase;
private String contextPath;
private String hostname;
private String baseDir;
public Client client;
public WebResource webResource;
public String response;
@Before
public final void setUp() throws Exception
{
this.PORT = 8081;
this.appBase = "src/main/webapp";
this.contextPath = "";
this.baseDir = ".";
this.hostname = "localhost";
this.tomcat = new Tomcat();
this.tomcat.setPort(this.PORT);
this.tomcat.setBaseDir(this.baseDir);
this.tomcat.getHost().setAppBase(this.appBase);
this.tomcat.setHostname(this.hostname);
Context ctx = this.tomcat.addWebapp(this.contextPath, this.appBase);
File contextFile = new File(this.appBase + "/WEB-INF/web.xml");
ctx.setConfigFile(contextFile.toURI().toURL());
this.tomcat.start();
this.tomcat.getServer().await();
}
@After
public final void tearDown() throws Exception
{
this.tomcat.stop();
}
}
以及一个用于测试URL的典型测试类:
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sproutcore.sample.todos.AbstractMainHTTPTestCase;
public class MainControllerTest extends AbstractMainHTTPTestCase
{
private static final Logger LOG = LoggerFactory.getLogger(MainControllerTest.class);
@Test
public void staticTest() throws Exception
{
LOG.debug("HTTP TEST: staticTest");
this.response = this.webResource.path("/static/test.txt").get(String.class);
LOG.debug("staticTest response: {}", this.response);
assertNotNull("Static test shall be not null", this.response);
}
}
在applicationcontext.xml中配置静态文件夹:
<!-- Handles HTTP GET requests for /static/** -->
<mvc:resources mapping="/static/**" location="/static/" />
这种工作方式/允许人们编写第一个单元测试和代码创建数据单元测试,然后编写应用程序功能。使用 Maven 打包应用程序时会自动执行测试。您也可以生成测试报告...最佳实践...
The aim is to, for each unit test, systematically start a tomcat 7 server, load the spring application (eventually drop / create a schema & init its data in an database) perform unit tests and stop the http server.
It is quite easy to found sample in order to do that with jetty embedded server
I DONT found the right way to configure the embedded tomcat 7 server in order to load spring context
Can you please help me ??
project structure is a standard maven webApp project named "myApp"
src
+-main
+-java
+-webapp
+-static
+-WEB-INF
+-web.xml
+-applicationcontext.xml
target
+-myApp
+-webapp
+-static
+-WEB-INF
+-classes
the abstract unit test:
import org.junit.After;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.apache.catalina.Context;
import org.apache.catalina.core.AprLifecycleListener;
import org.apache.catalina.core.StandardServer;
import org.apache.catalina.startup.Tomcat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"applicationContext.xml"})
public abstract class AbstractMainHTTPTestCase
{
private int PORT;
private Tomcat tomcat;
private String appBase;
private String contextPath;
private String hostname;
private String baseDir;
public Client client;
public WebResource webResource;
public String response;
@Before
public final void setUp() throws Exception
{
this.PORT = 8081;
this.appBase = "src/main/webapp";
this.contextPath = "";
this.baseDir = ".";
this.hostname = "localhost";
this.tomcat = new Tomcat();
this.tomcat.setPort(this.PORT);
this.tomcat.setBaseDir(this.baseDir);
this.tomcat.getHost().setAppBase(this.appBase);
this.tomcat.setHostname(this.hostname);
Context ctx = this.tomcat.addWebapp(this.contextPath, this.appBase);
File contextFile = new File(this.appBase + "/WEB-INF/web.xml");
ctx.setConfigFile(contextFile.toURI().toURL());
this.tomcat.start();
this.tomcat.getServer().await();
}
@After
public final void tearDown() throws Exception
{
this.tomcat.stop();
}
}
and a typical test class for testing an URL:
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sproutcore.sample.todos.AbstractMainHTTPTestCase;
public class MainControllerTest extends AbstractMainHTTPTestCase
{
private static final Logger LOG = LoggerFactory.getLogger(MainControllerTest.class);
@Test
public void staticTest() throws Exception
{
LOG.debug("HTTP TEST: staticTest");
this.response = this.webResource.path("/static/test.txt").get(String.class);
LOG.debug("staticTest response: {}", this.response);
assertNotNull("Static test shall be not null", this.response);
}
}
Static folder is configured in applicationcontext.xml:
<!-- Handles HTTP GET requests for /static/** -->
<mvc:resources mapping="/static/**" location="/static/" />
This way of working force / allow people to code first unit tests & create data unit test, then to code application functions. Tests are automatically performed when packaging application with maven. You can generate tests reports too... Best practices...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您能更具体地说明什么不适用于此吗?
我认为这可能是两件事。
第一。
this.tomcat.getServer().await();
阻止线程,因此不会调用测试方法,我正在浏览相同的内容,如果您有来自 http://www.copperykeenclaws.com/embedding-tomcat-7/,这仅在以下情况下有意义主要方法
2。这可能是这个注释的问题
,让 JUnit-Runner 加载 spring 配置。所以我可以想象当tomcat再次加载spring配置时可能会发生冲突。
can you be a little more specific about what does not work with this?
i think it could be 2 things.
1st.
this.tomcat.getServer().await();
blocks the thread so no test-methods get invoked, i was browsing for the same thing and if you have your code from http://www.copperykeenclaws.com/embedding-tomcat-7/, this only makes sense in a main-method
2nd. it's maybe a problem with
this annotation lets the JUnit-Runner load the spring configuration. so i can imagine that there could be a conflict when the tomcat loads the spring-configuration again.