如何使用独立 tomcat runner 进行 spock 集成测试?

How to spock integration test with standalone tomcat runner?

我们的项目目前没有使用 spring 框架。

因此,它正在基于独立 tomcat 运行器进行测试。

但是,由于@SpringBootTest等集成化测试是不可能的,所以提前操作了Tomcat,使用Spock进行了HTTPAPI测试

有没有办法像 @SpringBootTest 那样改变它?

  1. Tomcat亚军
 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 测试示例
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"
        }
    }
}

如果去掉下面的注释,测试将无法进行。

// static final Tomcat8Launcher tomcat = new Tomcat8Launcher()

这一行指定API在顶部测试。

// tomcat.main()

此行已指定API测试setupSpec()方法

不知道为什么,Tomcat运行后只记录日志,没有执行测试方法

有办法解决这个问题吗?

我建议创建一个 Spock 扩展来封装您需要的一切。请参阅 Spock 文档的 writing custom extensions 以及内置扩展以获取灵感。