Add Randomized Responses to Moco API Mock Server

This guide shows how to extend Moco with a custom RandomHandler that selects one of several predefined responses at runtime, providing full Java code, helper methods, and a usage example for building more realistic mock APIs.

FunTester
FunTester
FunTester
Add Randomized Responses to Moco API Mock Server

Problem

When using the Moco API to create mock services, some endpoints need to return one of several predefined responses chosen at random. Moco does not provide this capability out of the box.

Solution – RandomHandler

A custom ResponseHandler is implemented by extending AbstractResponseHandler. The handler stores an immutable list of delegate ResponseHandler objects and selects one of them for each request.

package com.fun.moco.support;

import com.fun.frame.SourceCode;
import com.github.dreamhead.moco.MocoConfig;
import com.github.dreamhead.moco.ResponseHandler;
import com.github.dreamhead.moco.handler.AbstractResponseHandler;
import com.github.dreamhead.moco.internal.SessionContext;
import com.google.common.base.Function;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.FluentIterable.from;
import static com.google.common.collect.ImmutableList.copyOf;

/** Random response handler */
public class RandomHandler extends AbstractResponseHandler {
    private final ImmutableList<ResponseHandler> handlers;

    private RandomHandler(final Iterable<ResponseHandler> handlers) {
        this.handlers = copyOf(handlers);
    }

    /** Create a handler from a non‑empty collection of delegates */
    public static ResponseHandler newSeq(final Iterable<ResponseHandler> handlers) {
        checkArgument(Iterables.size(handlers) > 0, "Sequence contents should not be null");
        return new RandomHandler(handlers);
    }

    /** Choose a delegate at random and write its response */
    @Override
    public void writeToResponse(final SessionContext context) {
        int index = SourceCode.getRandomInt(handlers.size()) - 1; // getRandomInt returns 1‑based value
        handlers.get(index).writeToResponse(context);
    }

    /** Apply a Moco configuration to every delegate */
    @Override
    public ResponseHandler apply(final MocoConfig config) {
        if (config.isFor(MocoConfig.RESPONSE_ID)) {
            return super.apply(config);
        }
        FluentIterable<ResponseHandler> transformed = from(copyOf(handlers)).transform(applyConfig(config));
        return new RandomHandler(transformed.toList());
    }

    private Function<ResponseHandler, ResponseHandler> applyConfig(final MocoConfig config) {
        return new Function<ResponseHandler, ResponseHandler>() {
            @Override
            public ResponseHandler apply(final ResponseHandler input) {
                return input.apply(config);
            }
        };
    }
}

Key methods

writeToResponse(SessionContext)

– selects a random delegate using SourceCode.getRandomInt and forwards the call. apply(MocoConfig) – propagates a Moco configuration to each delegate, returning a new RandomHandler with the transformed list. newSeq(Iterable<ResponseHandler>) – static factory that validates the input and creates the handler.

Convenient static factory methods

Three overloads are provided to build a RandomHandler from common data types. They convert the inputs to ResponseHandler instances (using an assumed textToResource() utility) and then delegate to RandomHandler.newSeq.

/** Random response from plain strings */
static ResponseHandler random(String content, String... contents) {
    return RandomHandler.newSeq(
        FluentIterable.from(asIterable(content, contents)).transform(textToResource())
    );
}

/** Random response from JSON objects */
static ResponseHandler random(JSONObject json, JSONObject... jsons) {
    return RandomHandler.newSeq(
        FluentIterable.from(
            asIterable(json.toString(), jsons.toList().stream().map(x -> x.toString()).toArray(String[]::new))
        ).transform(textToResource())
    );
}

/** Random response from existing handlers */
static ResponseHandler random(ResponseHandler handler, ResponseHandler... handlers) {
    return RandomHandler.newSeq(asIterable(handler, handlers));
}

Usage example

Integrate the handler into a Moco server configuration. Each request to /find will receive one of the three strings chosen at random.

server.get(urlOnly("/find")).response(
    random("43242=342", "e343=fdsf", "3242")
);

This approach adds randomised response behaviour without modifying the core Moco library, enabling more realistic test scenarios.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavatestingAPIMock ServerMoCoRandom Response
FunTester
Written by

FunTester

10k followers, 1k articles | completely useless

0 followers
Reader feedback

How this landed with the community

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.