简体   繁体   中英

How to spock integration test with standalone tomcat runner?

Our project is not currently using a spring framework.

Therefore, it is being tested based on the standalone tomcat runner.

However, since integration-enabled tests such as @SpringBootTest are not possible, Tomcat is operated in advance and the HTTP API test is carried out using Spock.

Is there a way to turn this like @SpringBootTest ?

  1. TomcatRunner
 private Tomcat tomcat = null;
    private int port = 8080;
    private String contextPath = null;
    private String docBase = null;
    private Context rootContext = null;

    public Tomcat8Launcher(){
        init();
    }

    public Tomcat8Launcher(int port, String contextPath, String docBase){
        this.port = port;
        this.contextPath = contextPath;
        this.docBase = docBase;
        init();
    }

    private void init(){
        tomcat = new Tomcat();
        tomcat.setPort(port);
        tomcat.enableNaming();
        if(contextPath == null){
            contextPath = "";
        }
        if(docBase == null){
            File base = new File(System.getProperty("java.io.tmpdir"));
            docBase = base.getAbsolutePath();
        }
        rootContext = tomcat.addContext(contextPath, docBase);
    }

    public void addServlet(String servletName, String uri, HttpServlet servlet){
        Tomcat.addServlet(this.rootContext, servletName, servlet);
        rootContext.addServletMapping(uri, servletName);
    }

    public void addListenerServlet(ServletContextListener listener){
        rootContext.addApplicationListener(listener.getClass().getName());
    }

    public void startServer() throws LifecycleException {
        tomcat.start();
        tomcat.getServer().await();
    }

    public void stopServer() throws LifecycleException {
        tomcat.stop();
    }

    public static void main(String[] args) throws Exception {
        System.setProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager");
        System.setProperty(javax.naming.Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
        System.setProperty(javax.naming.Context.URL_PKG_PREFIXES, "org.apache.naming");

        Tomcat8Launcher tomcatServer = new Tomcat8Launcher();
        tomcatServer.addListenerServlet(new ConfigInitBaseServlet());
        tomcatServer.addServlet("restServlet", "/rest/*", new RestServlet());
        tomcatServer.addServlet("jsonServlet", "/json/*", new JsonServlet());
        tomcatServer.startServer();
    }
  1. Spock API Test example
class apiTest extends Specification {
    //static final Tomcat8Launcher tomcat = new Tomcat8Launcher()
    static final String testURL = "http://localhost:8080/api/"

    @Shared
    def restClient

    def setupSpec() {
        // tomcat.main()
        restClient = new RESTClient(testURL)
    }

    def 'findAll user'() {
        when:
        def response = restClient.get([path: 'user/all'])

        then:
        with(response){
            status == 200
            contentType == "application/json"
        }
    }
}

The test will not work if the annotations are removed from the annotations below.

// static final Tomcat8Launcher tomcat = new Tomcat8Launcher()

This line is specified API Test at the top.

// tomcat.main()

This line is specified API Test setupSpec() method

I don't know why, but only logs are recorded after Tomcat has operated and the test method is not executed.

Is there a way to fix this?

I would suggest to create a Spock extension to encapsulate everything you need. See writing custom extensions of the Spock docs as well as the built-in extensions for inspiration.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM