Package org.mockserver.junit

Source Code of org.mockserver.junit.ProxyRule$ClientAndProxyFactory

package org.mockserver.junit;

import com.google.common.annotations.VisibleForTesting;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.mockserver.client.proxy.ProxyClient;
import org.mockserver.integration.ClientAndProxy;
import org.mockserver.socket.PortFactory;

import java.lang.reflect.Field;

public class ProxyRule implements TestRule {

    private static ClientAndProxy perTestSuiteClientAndProxy;
    private final Object target;
    private final Integer httpPort;
    private final Integer httpsPort;
    private final boolean perTestSuite;
    private ClientAndProxyFactory clientAndProxyFactory;

    /**
     * Start the proxy prior to test execution and stop the proxy after the tests have completed.
     * This constructor dynamically allocates a free port for the proxy to use.
     * Note: The getHttpPort getter can be used to retrieve the dynamically allocated port.
     *
     * @param target an instance of the test being executed
     */
    public ProxyRule(Object target) {
        this(PortFactory.findFreePort(), target);
    }

    /**
     * Start the proxy prior to test execution and stop the proxy after the tests have completed.
     * This constructor dynamically allocates a free port for the proxy to use.
     *
     * @param target an instance of the test being executed
     * @param perTestSuite indicates how many instances of the proxy are created
     *                     if true a single proxy is created per JVM
     *                     if false one instance per test class is created
     */
    public ProxyRule(Object target, boolean perTestSuite) {
        this(PortFactory.findFreePort(), target, perTestSuite);
    }

    /**
     * Start the proxy prior to test execution and stop the proxy after the tests have completed.
     * This constructor dynamically create a proxy that accepts HTTP requests on the specified port
     *
     * @param httpPort the HTTP port for the proxy
     * @param target an instance of the test being executed
     */
    public ProxyRule(Integer httpPort, Object target) {
        this(httpPort, null, target, false);
    }

    /**
     * Start the proxy prior to test execution and stop the proxy after the tests have completed.
     * This constructor dynamically create a proxy that accepts HTTP requests on the specified port
     *
     * @param httpPort the HTTP port for the proxy
     * @param target an instance of the test being executed
     * @param perTestSuite indicates how many instances of the proxy are created
     *                     if true a single proxy is created per JVM
     *                     if false one instance per test class is created
     */
    public ProxyRule(Integer httpPort, Object target, boolean perTestSuite) {
        this(httpPort, null, target, perTestSuite);
    }

    /**
     * Start the proxy prior to test execution and stop the proxy after the tests have completed.
     * This constructor dynamically create a proxy that accepts HTTP and HTTPS requests on the specified ports
     *
     * @param httpPort the HTTP port for the proxy
     * @param httpsPort the HTTPS port for the proxy
     * @param target an instance of the test being executed
     * @param perTestSuite indicates how many instances of the proxy are created
     *                     if true a single proxy is created per JVM
     *                     if false one instance per test class is created
     */
    public ProxyRule(Integer httpPort, Integer httpsPort, Object target, boolean perTestSuite) {
        this.httpPort = httpPort;
        this.httpsPort = httpsPort;
        this.target = target;
        this.perTestSuite = perTestSuite;
        this.clientAndProxyFactory = new ClientAndProxyFactory(httpPort, httpsPort);
    }

    public Integer getHttpPort() {
        return httpPort;
    }

    public Integer getHttpsPort() {
        return httpsPort;
    }

    public Statement apply(Statement base, Description description) {
        return statement(base);
    }

    private Statement statement(final Statement base) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                ClientAndProxy clientAndProxy;
                if (perTestSuite) {
                    if (perTestSuiteClientAndProxy == null) {
                        perTestSuiteClientAndProxy = clientAndProxyFactory.newClientAndProxy();
                        Runtime.getRuntime().addShutdownHook(new Thread() {
                            @Override
                            public void run() {
                                perTestSuiteClientAndProxy.stop();
                            }
                        });
                    }
                    clientAndProxy = perTestSuiteClientAndProxy;
                } else {
                    clientAndProxy = clientAndProxyFactory.newClientAndProxy();
                }
                setProxyClient(target, clientAndProxy);
                try {
                    base.evaluate();
                } finally {
                    if (!perTestSuite) {
                        clientAndProxy.stop();
                    }
                }
            }
        };
    }

    private void setProxyClient(Object target, ClientAndProxy clientAndProxy) {
        for (Field field : target.getClass().getDeclaredFields()) {
            if (field.getType().equals(ProxyClient.class)) {
                field.setAccessible(true);
                try {
                    field.set(target, clientAndProxy);
                } catch (IllegalAccessException e) {
                    throw new RuntimeException("Error setting ProxyClient field on " + target.getClass().getName(), e);
                }
            }
        }
    }

    @VisibleForTesting
    class ClientAndProxyFactory {
        private final Integer httpPort;
        private final Integer httpsPort;

        public ClientAndProxyFactory(Integer httpPort, Integer httpsPort) {
            this.httpPort = httpPort;
            this.httpsPort = httpsPort;
        }

        public ClientAndProxy newClientAndProxy() {
            if (httpsPort == null) {
                return ClientAndProxy.startClientAndProxy(httpPort);
            } else {
                return ClientAndProxy.startClientAndProxy(httpPort, httpsPort);
            }
        }
    }
}
TOP

Related Classes of org.mockserver.junit.ProxyRule$ClientAndProxyFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.