Testing Workflow
A step-by-step workflow for building NestForge tests around modules, HTTP routes, GraphQL, gRPC, and microservice handlers.
This guide turns the testing helpers into a practical workflow instead of a reference.
Use this sequence when you want to test a NestForge app:
- build a testing module
- override any providers that should differ in tests
- pick the transport surface you want to test
- make assertions
- shut the module down if lifecycle hooks matter
Step 1: build the testing module
Section titled “Step 1: build the testing module”The normal entry point is TestFactory::<AppModule>:
let module = nestforge::TestFactory::<AppModule>::create() .override_provider(AppConfig { app_name: "test".to_string(), log_level: "debug".to_string(), }) .build()?;This gives you a full module runtime with the NestForge container and controller graph.
Step 2: resolve providers directly
Section titled “Step 2: resolve providers directly”Before testing a route or transport edge, verify the container state when needed:
let config = module.resolve::<AppConfig>()?;This is useful for checking that provider overrides were applied before request handling or message dispatch starts.
Step 3: choose the surface to test
Section titled “Step 3: choose the surface to test”HTTP workflow
Section titled “HTTP workflow”If you want to test controller routes, use http_router():
let response = module .http_router() .oneshot( axum::http::Request::builder() .uri("/health") .body(axum::body::Body::empty())?, ) .await?;Use this when you want to verify:
- route matching
- request validation
- controller behavior
- response status and body
GraphQL workflow
Section titled “GraphQL workflow”If your app exposes GraphQL, mount the schema into the testing module:
let app = module.graphql_router(schema);Use this when you want to verify:
- resolver behavior
- schema wiring
- provider resolution from GraphQL context
gRPC workflow
Section titled “gRPC workflow”If you need DI-backed transport logic without running a server, use:
let ctx = module.grpc_context();This is useful for testing service behavior that depends on GrpcContext.
Microservice workflow
Section titled “Microservice workflow”To test pattern handlers directly:
let ctx = module.microservice_context("test", "users.count");Or create an in-process client against a registry:
let client = module.microservice_client(registry.clone(), "test");Use this when you want to verify:
- pattern dispatch
- event handling
- transport metadata
- provider resolution from
MicroserviceContext
Step 4: prefer the smallest useful scope
Section titled “Step 4: prefer the smallest useful scope”Use this rule:
- test the provider directly when only business logic matters
- test
http_router()when route behavior matters - test GraphQL router when schema integration matters
- test
grpc_context()when gRPC service code depends on DI - test microservice context or client when pattern dispatch matters
That keeps tests fast and makes failures easier to localize.
Step 5: shut down cleanly
Section titled “Step 5: shut down cleanly”If your module uses lifecycle hooks, finish with:
module.shutdown()?;That runs destroy and shutdown hooks inside the testing runtime.
Common testing sequence
Section titled “Common testing sequence”For most apps, a practical order is:
- provider tests
- HTTP route tests
- GraphQL or transport-specific tests
- in-process microservice tests
That order catches logic bugs before you spend time debugging transport behavior.
What to read next
Section titled “What to read next”For the API reference version of these helpers, see Testing.