---
question: How do I test an integration without the real API?
kind: task
via_web: na
via_cli: available
via_python: available
via_api: na
via_config: na
ref_cli: uv run pytest
ref_python: unittest.mock.patch
prereq: You need an integration class with its HTTP call in one method. See [Create an integration](/user-guide/build/agents/creating-an-integration).
next:
  - /capabilities/build/integrations/use-in-an-agent
  - /capabilities/build/modules/test-a-module
---

# Test an integration

Test an integration as plain Python: build the class with a fake key, replace its HTTP call, and check what it returns. No engine and no network.

Keep the test next to the class, as `<Name>Integration_test.py`. Keep tests that call the real service in a separate `<Name>Integration_integration_test.py`, with a skip when the credential is missing: see [Skip live tests without credentials](#skip-live-tests-without-credentials). `abi new integration` writes no test file.

## Web UI

Not applicable. Nexus has no screen that runs an integration or its tests. Run them with the CLI. To try an integration through an agent, see [Use in an agent](/user-guide/build/integrations/use-in-an-agent).

## CLI

### Run the module's integration tests

From the project root:

```bash
uv run pytest src/my_module/integrations
```

pytest collects every `*_test.py` file in the folder.

### Run one file

```bash
uv run pytest src/my_module/integrations/MyIntegration_test.py -v
```

There is no `abi` command that tests an integration.

## Python

### Write the test

Patch the method the class uses for HTTP. In the example on [Create an integration](/user-guide/build/agents/creating-an-integration), that is `_make_request`:

```python title="integrations/MyIntegration_test.py"
from unittest.mock import patch

from my_module.integrations.MyIntegration import (
    MyIntegration,
    MyIntegrationConfiguration,
)


def test_list_items():
    integration = MyIntegration(MyIntegrationConfiguration(api_key="test-key"))
    with patch.object(integration, "_make_request", return_value=[{"id": "1"}]) as request:
        result = integration.list_items(filter="open")
    assert result == [{"id": "1"}]
    request.assert_called_once_with("/items", params={"filter": "open"})
```

### Or patch the HTTP library

When the class calls `requests`, patch `requests.request` itself. `patch` replaces the attribute on the shared `requests` module, so it works whether the class imports `requests` at the top of the file or inside a method:

```python title="integrations/MyIntegration_test.py"
from unittest.mock import MagicMock, patch

from my_module.integrations.MyIntegration import (
    MyIntegration,
    MyIntegrationConfiguration,
)


@patch("requests.request")
def test_get_item(mock_request):
    mock_request.return_value = MagicMock(json=lambda: {"id": "1"})
    integration = MyIntegration(MyIntegrationConfiguration(api_key="test-key"))
    assert integration.get_item("1") == {"id": "1"}
```

### Test the tools

`as_tools(configuration)` returns LangChain tools. Call one with its arguments to check the schema and the wiring. In the same test file:

```python title="integrations/MyIntegration_test.py"
from my_module.integrations.MyIntegration import as_tools


def test_tools():
    tools = {tool.name: tool for tool in as_tools(MyIntegrationConfiguration(api_key="test-key"))}
    with patch.object(MyIntegration, "_make_request", return_value=[]):
        assert tools["list_myservice_items"].invoke({"filter": "open"}) == []
```

## REST API

Not applicable. The API process has no route for integrations: it does not call or test them. Test with the CLI or Python.

## Config

Not applicable. Tests build the configuration in code with a fake key. They do not read `config.yaml` or the secret service.

## Skip live tests without credentials

`<Name>Integration_integration_test.py` still ends in `_test.py`, so `uv run pytest` collects it with the others. Skip it when the key is not set, so a run without credentials passes:

```python title="integrations/MyIntegration_integration_test.py"
import os

import pytest

from my_module.integrations.MyIntegration import (
    MyIntegration,
    MyIntegrationConfiguration,
)

pytestmark = pytest.mark.skipif(
    not os.getenv("MY_API_KEY"), reason="MY_API_KEY is not set"
)


def test_list_items_live():
    integration = MyIntegration(MyIntegrationConfiguration(api_key=os.environ["MY_API_KEY"]))
    assert isinstance(integration.list_items(), list)
```

Export `MY_API_KEY` in the shell (or load `.env` into it) to run them against the real service.
