Skip to content

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:

  1. build a testing module
  2. override any providers that should differ in tests
  3. pick the transport surface you want to test
  4. make assertions
  5. shut the module down if lifecycle hooks matter

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.

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.

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

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

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.

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

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.

If your module uses lifecycle hooks, finish with:

module.shutdown()?;

That runs destroy and shutdown hooks inside the testing runtime.

For most apps, a practical order is:

  1. provider tests
  2. HTTP route tests
  3. GraphQL or transport-specific tests
  4. in-process microservice tests

That order catches logic bugs before you spend time debugging transport behavior.

For the API reference version of these helpers, see Testing.