Backend Development 11 min read

EasyMock Platform Overview and JSF Mock Implementation Techniques

This article introduces the EasyMock platform, explains its role in providing JSF and HTTP mock services for development and testing, outlines its architecture and capabilities, and details the step‑by‑step technical implementation of JSF Mock including jar downloading, JVM class loading, dynamic proxy creation, registration, client invocation, parameter matching, and response deserialization.

JD Retail Technology
JD Retail Technology
JD Retail Technology
EasyMock Platform Overview and JSF Mock Implementation Techniques

The article presents EasyMock, a platform designed for the group's product, development, and testing teams that offers full‑stack server‑side mock services for JSF and HTTP interfaces, supporting test and production environments, multi‑site deployments, and flexible request/response configuration.

Since its launch in October 2021, EasyMock has been adopted by 49 departments across retail, technology, logistics, and health units, serving over 2,000 users with more than ten million mock calls per month.

It addresses common challenges such as unavailable dependent services, complex or exceptional data scenarios, frequent data changes, and tight testing schedules, thereby improving automated test pass rates.

Key platform capabilities include multi‑protocol support (JSF, HTTP), environment selection, version and alias handling, method‑level pass‑through, parameter template management (regex matching, auto‑parsing, generation, parameterization, exception simulation), open APIs for integration, and performance testing support.

The overall architecture follows a master‑slave deployment: the master service manages templates, dashboards, and controls mock activation on slave services, which actually provide the mock responses.

JSF Mock implementation proceeds through several technical steps:

Jar package download based on Maven coordinates, performed asynchronously via @EnableAsync and Maven commands.

JVM loading of the downloaded JARs using URLClassLoader and reflective invocation of the addURL method.

Class instantiation via dynamic proxy, employing InvocationHandler and Proxy.newProxyInstance to create mock instances.

Registration of the mock interface with the JSF registry.

Client invocation of the mock alias, triggering the slave service to match the request against configured templates.

Parameter matching using object conversion, full/partial string matching, regex, and default wildcard strategies.

Response generation by deserializing the matched template using fastjson, gson, or custom POJO utilities.

Relevant code examples are preserved below:

// Obtain system class loader
URLClassLoader urlClassLoaderForJvm = (URLClassLoader) ClassLoader.getSystemClassLoader();
Class<URLClassLoader> urlClass = URLClassLoader.class;
Method method = urlClass.getDeclaredMethod("addURL", new Class[]{URL.class});
method.setAccessible(true);
for (File file : files) {
    logger.info("Dynamic loading jar: {}", file.getAbsolutePath());
    URL url = new URL("file:" + file);
    method.invoke(urlClassLoaderForJvm, new Object[]{ url });
}
try {
    cls = urlClassLoaderForJvm.loadClass(interfaceName);
} catch (NoClassDefFoundError e) {
    logger.error("Cannot resolve class: " + interfaceName);
} catch (Exception e) {
    logger.error("Class resolution error: " + e.toString());
}
@Service
public class FacadeProxy implements InvocationHandler {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Exception {
        // mock handling
        String response = matchParams(methodId, args, method);
        return new Gson().fromJson(response, method.getReturnType());
    }
    public static
T newMapperProxy(Class
mapperInterface) throws Throwable {
        ClassLoader classLoader = mapperInterface.getClassLoader();
        Class
[] interfaces = new Class[] { mapperInterface };
        FacadeProxy proxy = new FacadeProxy();
        return (T) Proxy.newProxyInstance(classLoader, interfaces, proxy);
    }
}
// Parameter handling example
Type genericReturnType = method.getGenericReturnType();
Object object;
// Basic type conversion
object = Integer.valueOf(response);
// Fastjson conversion
object = JSON.parseObject(resultString, genericReturnType);
// Fallback to Gson
object = gson.fromJson(resultString, genericReturnType);
// Complex object handling via PojoUtils
object = PojoUtils.realize(JSON.parseObject(resultString, Map.class), genericReturnType.getClass());

The article concludes that the JSF Mock implementation is now functional, with future articles planned to cover HTTP Mock and additional technical challenges, and invites the community to contribute to the open‑source effort.

backendJavamockingClassLoaderDynamic ProxyJSF
JD Retail Technology
Written by

JD Retail Technology

Official platform of JD Retail Technology, delivering insightful R&D news and a deep look into the lives and work of technologists.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.