KKeploy Tutorial
Keploy QuickstartGoGinRedisWSL2

Testing a Go API without touching Redis

Record real API traffic with Keploy, then replay it as tests with auto-generated mocks, no live database required. Written from a real Windows machine, including the parts most tutorials skip.

~20 minute read · beginner friendly · no Keploy experience assumed

I run Windows. Most Go tutorials assume you don’t. This guide covers the full WSL2 setup so you can use Keploy without skipping the hard parts.

By the end of this, you'll have
  • A Go + Gin + Redis authentication API running locally
  • Keploy recording your real API calls as test cases
  • Those tests replaying without Redis running, using auto-generated mocks

Why Windows Users Need a Detour

Keploy doesn't run natively on Windows the way it does on Linux, eBPF is a Linux kernel feature. Your options:

OptionThe short version
WSL2 (what I used)What every quickstart in Keploy's docs actually assumes; Go tooling just behaves better in a real Linux shell
DockerRun everything containerized
Native Windows buildAMD-only, admin rights required

I went with WSL2, and the four setup steps below get you from a bare Windows machine to a Keploy-ready Linux environment.

1

Setting up WSL2 + Ubuntu

PowerShell (Run as Administrator)
wsl --install -d Ubuntu-22.04

Run this in an elevated PowerShell window (right-click → Run as Administrator). It downloads Ubuntu, and on first launch asks you to create a Linux username and password, separate from your Windows login.

Once inside Ubuntu, don't work out of your Windows filesystem (/mnt/c/...), move to your Linux home directory first:

cd ~

This avoids permission weirdness and is noticeably faster for anything involving go build or git.

2

Installing Go

Ubuntu's default apt package for Go is often years out of date (I got 1.18 when the current stable was well past 1.23). Skip apt and install directly from Go's official binary:

Ubuntu (WSL2)
wget https://go.dev/dl/go1.23.4.linux-amd64.tar.gz
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go1.23.4.linux-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
source ~/.bashrc
go version
3

Installing Keploy

Ubuntu (WSL2)
curl --silent -O -L https://keploy.io/install.sh && source install.sh
keploy --version

Then authenticate:

keploy login

This opens a browser tab to sign in. You have about a minute before the auth code expires, if you're slow to switch tabs, it'll time out and you'll just need to re-run the command.

4

Docker Desktop + WSL Integration

The Gin+Redis sample runs Redis in a container while the Go app runs natively in WSL. That means Docker Desktop needs to talk to your Ubuntu distro specifically:

Running the Gin + Redis Sample

This is a small OTP-based authentication API, request a code, verify it, get a token back.

Clone and fetch dependencies
git clone https://github.com/keploy/samples-go.git && cd samples-go/gin-redis
go mod download

Start Redis in the background:

docker compose up -d redis

Build the app:

go build -o gin-redis

Recording Test Cases

This is the actual Keploy step. Everything before this was just getting a Linux environment ready.

Start recording
sudo -E PATH="$PATH" keploy record -c "./gin-redis"

With that running, open a second terminal and make real API calls. First, request a verification code:

curl --location 'localhost:3001/api/getVerificationCode?email=something@gmail.com&username=shivamsourav'

Take the OTP from the response and verify it:

curl --location 'localhost:3001/api/verifyCode' \
  --header 'Content-Type: application/json' \
  --data-raw '{"otp":7454,"email":"something@gmail.com"}'

Stop the recording with Ctrl+C. Keploy writes everything it saw into a keploy/ folder:

ls -R keploy/

You'll find two things in there:

Test files

Your actual request/response pairs, each curl call you made, captured as a replayable test case.

Mocks file

The raw Redis protocol traffic that happened behind the scenes, SETs, GETs, EXPIREs, all captured verbatim.

Replaying Without Redis

This is the payoff. Stop your Redis container, or just trust that Keploy doesn't need it:

Run the recorded tests
keploy test -c './gin-redis' --mappings

Keploy replays your exact curl calls against a fresh instance of the app, but instead of hitting real Redis, it serves back the exact Redis responses it recorded earlier. No live database dependency, no test data drifting between runs, no "works on my machine."

The Bug That Taught Me the Most

My first replay attempt failed with status_code expected=200 got=500. Here's the debugging trail, because I think it's more useful than a clean success story.

The test report flagged SCHEMA_BROKEN, my replayed response was missing the token and username fields entirely, meaning the verify call failed on replay even though it had succeeded live. I checked the recorded mocks and found only 3 Redis mock entries, all handshake/config traffic (CLIENT SETINFO, module discovery). The actual SET and GET calls that store and retrieve the OTP were never captured.

The cause: I was running Redis via docker compose up redis, with Docker Desktop's WSL2 backend routing that traffic through its virtualized network layer. Keploy's eBPF hook, which watches Linux kernel network calls directly, never saw those specific packets, they were happening one layer removed from where it was looking.

Switching to native Redis fixed it immediately, mock count went from 3 to 5, now including the real SET otp and GET otp commands. Re-running the tests got me a passing getVerificationCode call, but verifyCode still flagged as failed: category: SCHEMA_UNCHANGED, with token as the only differing field.

That one wasn't a bug, it was expected. The JWT is signed fresh on every successful auth, so its exact string will never match between record and replay, the same way the OTP itself won't. Keploy's assertions.noise list is built exactly for this: fields you expect to legitimately differ between runs, so the test focuses on the response shape being correct rather than pinning volatile values.

test-2.yaml
assertions:
  noise:
    - body.token
    - body.otp
    - header.Date

With token added to that list, the suite goes fully green.

Quick Answers

A few questions I had to answer for myself along the way, collected in one place:

What This Actually Buys You

The interesting part isn't "look, tests pass." It's this:

CI without dependencies

Your integration tests no longer need a live Redis instance, database, or downstream service to run in CI.

Mocks that can't drift

The mocks are generated from real traffic, not hand-written stubs that quietly fall out of sync with what your API actually does.

Zero extra code

You're not instrumenting handlers or writing fixtures, you're just calling your API normally while Keploy watches.

If you're evaluating Keploy for a Go service with any kind of database or cache dependency, this Gin+Redis quickstart is the fastest way to feel that difference yourself, WSL setup aside.

One last thing worth saying plainly: the debugging above wasn't a detour from learning Keploy, it was learning Keploy. Understanding why the mocks came up short taught me more about how the eBPF interception actually works than a clean first-try run ever would have.