CLOUD CONCEPT

Mocking

Mocking replaces real dependencies with controlled test substitutes so application behavior can be tested in isolation.

Cloud Concepts Hub →

What is Mocking

Mocking lets engineers define how dependencies respond and verify how application code interacts with them without contacting live systems. It makes unit tests fast and repeatable, especially for cloud applications that depend on databases, queues, APIs, and other managed services.

Mocking is a testing technique that replaces a dependency with a controlled substitute. Instead of calling a real database, cloud SDK client, HTTP endpoint, or clock, the code under test interacts with an object or function configured by the test. The test can supply responses, raise exceptions, and inspect calls. This isolates application logic from network availability, credentials, changing data, and service costs.

Strictly speaking, a mock verifies interactions, such as whether a method was called with the expected arguments. A stub supplies predetermined responses, while a fake provides a simplified working implementation. Testing frameworks often combine these capabilities, and engineers commonly use the word mocking for several kinds of dependency substitution. The important design decision is which boundary the test replaces and which behavior remains real.

For example, consider a Lambda function that validates an order and writes it to DynamoDB. Separate validation and order processing from the handler's event-parsing code, and pass a database client or repository into the processing function. A unit test can provide a mock repository, submit a valid order, and verify that the expected record was written once. Another test can submit an invalid order and verify that no write was attempted. Neither test requires a deployed Lambda function or an actual table.

Error paths are equally important. Configure the dependency to raise an appropriate throttling, timeout, or conditional-write exception, then check the application's response. If application code implements retries, a sequence of failures followed by success can exercise that logic. However, replacing an entire SDK method does not exercise the SDK's own internal retry behavior. Tests should distinguish application responsibilities from behavior implemented by the SDK or service.

Use a language-appropriate framework, such as Python's unittest.mock or JavaScript's Jest, to create substitutes and assertions. Tools such as Botocore Stubber can supply modeled SDK responses without sending requests. Inject dependencies explicitly where practical, or patch the reference used by the module under test. Reset mocks between tests, use realistic response structures, and avoid loading credentials or contacting metadata endpoints merely to construct a test dependency.

AWS SAM supports serverless development, but local invocation and mocking solve different problems. Unit tests can import application functions and run directly through a test runner without SAM or Docker. The sam local invoke command runs a Lambda function locally in a container using a supplied event. It does not automatically replace downstream AWS calls: those calls can still reach real services unless dependencies are substituted or explicitly configured otherwise. Likewise, a Lambda console test event invokes the deployed function; it does not make the invocation an isolated unit test.

Mocks trade fidelity for speed and control. They cannot prove that IAM permissions, resource policies, network access, event-source configuration, or actual service behavior are correct. Overly detailed interaction assertions can also make tests fragile during harmless refactoring. Prefer assertions about meaningful outcomes and important side effects, then complement mocked unit tests with integration tests against isolated cloud resources. This combination catches logic errors early while still validating the application's deployed behavior.

Key aspects of Mocking

Effective mocking combines isolated dependencies, controlled responses, meaningful assertions, and integration testing that covers what substitutes cannot validate.

Dependency isolation

Replace network clients, repositories, clocks, or other external dependencies at clear application boundaries. Keep the business logic under test real so failures point to application behavior rather than an unavailable dependency.

Deterministic responses and failures

Configure known return values, exceptions, and response sequences to reproduce success and failure cases. This makes rare conditions, such as throttling or duplicate-write conflicts, testable without inducing failures in live services.

Interaction verification

Assert important calls, arguments, and side effects, including that invalid input produces no external write. Avoid asserting incidental implementation details that do not affect correctness.

Testable application design

Separate handlers and event parsing from business logic, and inject external clients or adapters. This allows unit tests to run directly in development environments and CI without deploying infrastructure.

Explicit fidelity limits

A passing mock-based test proves behavior against the configured substitute, not against the actual service. Use integration tests to validate permissions, service contracts, networking, and event delivery.

Separation from local execution

Running an application locally does not automatically mock its dependencies. When using tools such as AWS SAM CLI, explicitly determine which calls are substituted and which can reach real cloud resources.

Cloud services for Mocking

For a serverless application, engineers can unit-test Lambda business logic with mocked SDK clients, then run the same suite in CodeBuild on each change. AWS SAM CLI can additionally exercise local Lambda execution with representative events, but downstream dependencies must still be explicitly substituted or allowed to use real resources. API Gateway REST API MOCK integrations can provide controlled HTTP responses while clients and backends are developed independently. Follow these fast, controlled checks with integration tests against isolated deployed resources to verify real permissions, request mappings, event delivery, and service interactions.

AWS Lambda image AWS Lambda

Lambda application code can be unit-tested by invoking handlers or business functions with synthetic events and mocked dependencies. Console test events invoke deployed functions and do not automatically isolate downstream calls; AWS SAM CLI provides local execution but also requires explicit control of those dependencies.

Open AWS Lambda →
Amazon API Gateway image Amazon API Gateway

API Gateway REST APIs support MOCK integrations that return configured responses without invoking a backend. These are useful for developing clients and checking API response handling before backend implementation, but they do not validate the eventual backend's behavior.

Open Amazon API Gateway →
AWS CodeBuild image AWS CodeBuild

CodeBuild can run unit-test frameworks and mocked test suites as part of continuous integration. Properly isolated mocked tests do not need access to application resources, although the build environment may still require permissions for artifacts, logs, and dependency retrieval.

Open AWS CodeBuild →