| Crates.io | mockforge-test |
| lib.rs | mockforge-test |
| version | 0.3.21 |
| created_at | 2025-10-22 04:39:15.552865+00 |
| updated_at | 2025-12-31 16:20:21.365783+00 |
| description | Test utilities for MockForge - easy integration with Playwright and Vitest |
| homepage | https://mockforge.dev |
| repository | https://github.com/SaaSy-Solutions/mockforge |
| max_upload_size | |
| id | 1894968 |
| size | 273,344 |
Test utilities for MockForge - easy integration with test frameworks like Playwright, Vitest, and any Rust test framework.
Add this to your Cargo.toml:
[dev-dependencies]
mockforge-test = "0.1"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
use mockforge_test::MockForgeServer;
#[tokio::test]
async fn test_with_mockforge() {
// Start MockForge server (auto-assigns port)
let server = MockForgeServer::builder()
.build()
.await
.expect("Failed to start server");
// Server is ready - run your tests
let client = reqwest::Client::new();
let response = client
.get(format!("{}/users", server.base_url()))
.send()
.await
.expect("Failed to get users");
assert!(response.status().is_success());
// Server automatically stops when dropped
}
use mockforge_test::MockForgeServer;
#[tokio::test]
async fn test_with_custom_port() {
let server = MockForgeServer::builder()
.http_port(3000)
.build()
.await
.expect("Failed to start server");
assert_eq!(server.http_port(), 3000);
assert_eq!(server.base_url(), "http://localhost:3000");
}
use mockforge_test::MockForgeServer;
#[tokio::test]
async fn test_with_openapi_spec() {
let server = MockForgeServer::builder()
.spec_file("tests/fixtures/petstore.yaml")
.build()
.await
.expect("Failed to start server");
// Test your OpenAPI endpoints
let response = reqwest::get(format!("{}/pets", server.base_url()))
.await
.expect("Failed to get pets");
assert!(response.status().is_success());
}
Switch between different test scenarios on the fly:
use mockforge_test::MockForgeServer;
#[tokio::test]
async fn test_scenario_switching() {
let server = MockForgeServer::builder()
.build()
.await
.expect("Failed to start server");
// Test default scenario
// ...
// Switch to authenticated user scenario
server
.scenario("user-authenticated")
.await
.expect("Failed to switch scenario");
// Test authenticated endpoints
// ...
// Switch to error scenario
server
.scenario("server-errors")
.await
.expect("Failed to switch scenario");
// Test error handling
// ...
}
use mockforge_test::MockForgeServer;
#[tokio::test]
async fn test_with_workspace() {
let server = MockForgeServer::builder()
.build()
.await
.expect("Failed to start server");
// Load a workspace configuration
server
.load_workspace("tests/fixtures/test-workspace.json")
.await
.expect("Failed to load workspace");
// Test with the workspace configuration
// ...
}
use mockforge_test::MockForgeServer;
use serde_json::json;
#[tokio::test]
async fn test_dynamic_mocks() {
let server = MockForgeServer::builder()
.build()
.await
.expect("Failed to start server");
// Update mock for a specific endpoint
server
.update_mock(
"/users/123",
json!({
"id": 123,
"name": "Alice",
"email": "alice@example.com"
}),
)
.await
.expect("Failed to update mock");
// Test with the updated mock
let response = reqwest::get(format!("{}/users/123", server.base_url()))
.await
.expect("Failed to get user");
let user: serde_json::Value = response.json().await.unwrap();
assert_eq!(user["name"], "Alice");
}
use mockforge_test::MockForgeServer;
#[tokio::test]
async fn test_multi_protocol() {
let server = MockForgeServer::builder()
.http_port(3000)
.ws_port(3001)
.grpc_port(3002)
.build()
.await
.expect("Failed to start server");
// Test HTTP endpoint
let http_response = reqwest::get(format!("http://localhost:3000/health"))
.await
.expect("Failed to get health");
assert!(http_response.status().is_success());
// Test WebSocket, gRPC, etc.
// ...
}
use mockforge_test::MockForgeServer;
#[tokio::test]
async fn test_with_observability() {
let server = MockForgeServer::builder()
.enable_admin(true)
.admin_port(3100)
.enable_metrics(true)
.metrics_port(9090)
.build()
.await
.expect("Failed to start server");
// Access admin UI at http://localhost:3100
// Access metrics at http://localhost:9090/metrics
}
use mockforge_test::MockForgeServer;
#[tokio::test]
async fn test_with_profile() {
let server = MockForgeServer::builder()
.profile("testing")
.build()
.await
.expect("Failed to start server");
// Server uses the "testing" profile configuration
}
use mockforge_test::MockForgeServer;
#[tokio::test]
async fn test_with_custom_binary() {
let server = MockForgeServer::builder()
.binary_path("/path/to/mockforge")
.build()
.await
.expect("Failed to start server");
}
use mockforge_test::MockForgeServer;
#[tokio::test]
async fn test_health_check() {
let server = MockForgeServer::builder()
.build()
.await
.expect("Failed to start server");
// Check if server is ready
assert!(server.is_ready().await);
// Get detailed health status
let health = server.health_check().await.expect("Health check failed");
assert_eq!(health.status, "healthy");
println!("Server uptime: {}s", health.uptime_seconds);
println!("Server version: {}", health.version);
}
use mockforge_test::MockForgeServer;
#[tokio::test]
async fn test_server_stats() {
let server = MockForgeServer::builder()
.build()
.await
.expect("Failed to start server");
// Get server statistics
let stats = server.get_stats().await.expect("Failed to get stats");
println!("Server stats: {:?}", stats);
}
use mockforge_test::MockForgeServer;
#[tokio::test]
async fn test_reset_mocks() {
let server = MockForgeServer::builder()
.build()
.await
.expect("Failed to start server");
// Make some changes
server.update_mock("/test", serde_json::json!({"test": true}))
.await
.expect("Failed to update mock");
// Reset all mocks to initial state
server.reset().await.expect("Failed to reset mocks");
}
While this is a Rust crate, you can use it to spawn MockForge servers for JavaScript/TypeScript tests:
mockforge-testExample Rust helper:
// bin/test-server.rs
use mockforge_test::MockForgeServer;
#[tokio::main]
async fn main() {
let server = MockForgeServer::builder()
.http_port(3000)
.build()
.await
.expect("Failed to start server");
println!("MockForge server started on port {}", server.http_port());
// Keep running until interrupted
tokio::signal::ctrl_c().await.ok();
}
Then in your playwright.config.ts:
import { defineConfig } from '@playwright/test';
import { exec } from 'child_process';
export default defineConfig({
globalSetup: async () => {
// Start MockForge
const server = exec('cargo run --bin test-server');
// Wait for server to be ready
await new Promise(resolve => setTimeout(resolve, 2000));
return () => server.kill();
},
// ...
});
Similar to Playwright, create a Rust helper and call it from Vitest's globalSetup:
// vitest.config.ts
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
globalSetup: './test/setup.ts',
},
});
// test/setup.ts
import { exec } from 'child_process';
export async function setup() {
const server = exec('cargo run --bin test-server');
await new Promise(resolve => setTimeout(resolve, 2000));
return () => server.kill();
}
For native Rust testing, you can use the helper function:
use mockforge_test::with_mockforge;
#[tokio::test]
async fn test_with_helper() {
with_mockforge(|server| async move {
// Your test code here
let response = reqwest::get(format!("{}/health", server.base_url()))
.await?;
assert!(response.status().is_success());
Ok(())
})
.await
.expect("Test failed");
}
| Field | Type | Default | Description |
|---|---|---|---|
http_port |
u16 |
0 (auto) |
HTTP server port |
ws_port |
Option<u16> |
None |
WebSocket server port |
grpc_port |
Option<u16> |
None |
gRPC server port |
admin_port |
Option<u16> |
None |
Admin UI port |
metrics_port |
Option<u16> |
None |
Metrics/Prometheus port |
spec_file |
Option<PathBuf> |
None |
OpenAPI spec file path |
workspace_dir |
Option<PathBuf> |
None |
Workspace directory |
profile |
Option<String> |
None |
Configuration profile |
enable_admin |
bool |
false |
Enable admin UI |
enable_metrics |
bool |
false |
Enable metrics endpoint |
extra_args |
Vec<String> |
[] |
Additional CLI arguments |
health_timeout |
Duration |
30s |
Health check timeout |
health_interval |
Duration |
100ms |
Health check interval |
working_dir |
Option<PathBuf> |
None |
Working directory |
env_vars |
Vec<(String, String)> |
[] |
Environment variables |
binary_path |
Option<PathBuf> |
None |
Path to mockforge binary |
binary_pathcargo install mockforge-cliAll operations return Result<T, Error> where Error provides detailed information:
use mockforge_test::{MockForgeServer, Error};
#[tokio::test]
async fn test_error_handling() {
match MockForgeServer::builder().build().await {
Ok(server) => {
// Server started successfully
}
Err(Error::BinaryNotFound) => {
eprintln!("MockForge binary not found. Please install it first.");
}
Err(Error::HealthCheckTimeout(secs)) => {
eprintln!("Server didn't become healthy within {}s", secs);
}
Err(e) => {
eprintln!("Failed to start server: {}", e);
}
}
}
Enable logging to see detailed information:
// In your test setup
tracing_subscriber::fmt()
.with_env_filter("mockforge_test=debug")
.init();
Or set the RUST_LOG environment variable:
RUST_LOG=mockforge_test=debug cargo test
See the examples directory for complete working examples.
Contributions are welcome! Please see CONTRIBUTING.md for details.
This project is licensed under either of
at your option.