Testing RESTFul Spring 3 service with embedded Tomcat 7 / junit under a Maven WebApp project
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 serverI 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...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
@ContextConfiguration(locations = {"applicationContext.xml"})
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.
精彩评论