MockMC is a testing framework for Minecraft server software, forked from the excellent MockBukkit project. It provides complete mock implementations of server environments, allowing you to run unit tests for your plugins with speed and precision.
MockBukkit set the standard for Bukkit-based unit testing. However, as server APIs like Paper and Folia have expanded into thousands of methods, maintaining manual stubs became tedious.
While the original MockBukkit utilized metaminer to help generate stubs, it required manual overhead to keep the mock surface in sync. We created MockMC to solve these core architectural challenges.
We have completely overhauled the metaminer engine using JavaPoet. This shift moves MockMC to an "Engine First" strategy:
- Automated Source Generation: Uses JavaPoet for automated source generation directly from the server schemas.
- Type-Safe Inheritance: The generation engine parses and mirrors deep interface inheritance hierarchies and complex generic types straight out of the upstream source distributions.
- Universal Scraping Surface: The tool reads structures cleanly across ecosystems, enabling instant, automated runtime stub generations for Paper, Folia, Velocity, BungeeCord, and Waterfall.
- Zero-Lag Updates: Every method, even deep experimental tracking components added in a brand-new target server revision, is immediately generated with safe, type-specific fallback rules.
- Focus on Logic: Because our engine programmatically spins up the thousands of interface methods automatically, our human implementation efforts are focused strictly on simulating complex physics and block states.
MockMC is published to Maven Central for frictionless public resolution. Visual tracking releases are also mirrored directly to GitHub Packages.
Add the Paper public repository and drop MockMC into your dependencies block. No access tokens or credential configurations are required.
repositories {
mavenCentral()
maven { url = uri("https://repo.papermc.io/repository/maven-public/") }
}
// Helper to safely extract the Paper API version bundled in the MockMC manifest
fun getMockMCPaperVersion(): String {
return try {
val mockmcJar = configurations["testRuntimeClasspath"].incoming.files
.find { it.name.contains("mockmc-") }
if (mockmcJar != null) {
val jarFile = java.util.jar.JarFile(mockmcJar)
val paperVersion = jarFile.manifest.mainAttributes.getValue("Paper-Version")
jarFile.close()
paperVersion ?: "26.2"
} else "26.2"
} catch (e: Exception) { "26.2" }
}
dependencies {
testImplementation("io.github.secondlifegaming:mockmc-v26.2:0.0.5")
testImplementation("io.papermc.paper:paper-api:${getMockMCPaperVersion()}")
}
Add the Paper repository mapping and the library dependencies to your plugin’s pom.xml:
<repositories>
<repository>
<id>papermc</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>io.github.secondlifegaming</groupId>
<artifactId>mockmc-v26.2</artifactId>
<version>0.0.5</version><!-- mockmc-version -->
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>26.2</version>
<scope>test</scope>
</dependency>
</dependencies>
Initialize the mock server pipeline inside your unit test setup:
private ServerMock server;
private MyPlugin plugin;
@BeforeEach
public void setUp() {
server = MockMC.mock();
plugin = MockMC.load(MyPlugin.class);
}
@AfterEach
public void tearDown() {
MockMC.unmock();
}Rather than throwing UnimplementedOperationException when encountering an unmapped method block, MockMC utilizes a Total Coverage layer.
Because our automated code engine maps the entire API surface using JavaPoet source patterns, every single method is guaranteed to link cleanly at runtime. If a specific behavior has not been explicitly overwritten with complex logic yet, the engine provides Safe Defaults:
- Collections/Arrays: Returns clean, empty, non-null instances.
- Optionals: Returns standard
Optional.empty(). - Objects: Returns
nullor an isolated mock sub-stub where safe. - Primitives: Returns typical zeroed boundaries (e.g.,
false,0).
This setup ensures your active automated testing pipelines never encounter compilation breakage or unexpected failures due to minor structural additions in the upstream API.
