testcontainers-mockserver 7.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,101 @@
1
+ Metadata-Version: 2.4
2
+ Name: testcontainers-mockserver
3
+ Version: 7.1.0
4
+ Summary: Testcontainers module for MockServer
5
+ Author-email: James D Bloom <jamesdbloom@gmail.com>
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://www.mock-server.com
8
+ Project-URL: Repository, https://github.com/mock-server/mockserver
9
+ Project-URL: Documentation, https://www.mock-server.com/mock_server/mockserver_testcontainers.html
10
+ Keywords: testing,docker,mockserver,testcontainers,mocking
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Topic :: Software Development :: Testing
21
+ Requires-Python: >=3.9
22
+ Description-Content-Type: text/markdown
23
+ Requires-Dist: testcontainers>=4.0.0
24
+ Provides-Extra: test
25
+ Requires-Dist: pytest>=7.0; extra == "test"
26
+ Requires-Dist: requests>=2.20; extra == "test"
27
+
28
+ # testcontainers-mockserver
29
+
30
+ A [Testcontainers](https://testcontainers.com) module for [MockServer](https://www.mock-server.com) in Python.
31
+
32
+ Starts a `mockserver/mockserver` Docker container, waits for readiness, and provides
33
+ convenient accessors for the mapped host, port, and URL.
34
+
35
+ ## Installation
36
+
37
+ ```bash
38
+ pip install testcontainers-mockserver
39
+ ```
40
+
41
+ ## Usage
42
+
43
+ ```python
44
+ from testcontainers_mockserver import MockServerContainer
45
+ import requests
46
+
47
+ with MockServerContainer() as mockserver:
48
+ url = mockserver.get_url() # e.g. "http://localhost:49152"
49
+
50
+ # Create an expectation
51
+ requests.put(f"{url}/mockserver/expectation", json={
52
+ "httpRequest": {"method": "GET", "path": "/hello"},
53
+ "httpResponse": {"statusCode": 200, "body": "world"},
54
+ })
55
+
56
+ # Match it
57
+ resp = requests.get(f"{url}/hello")
58
+ assert resp.text == "world"
59
+ ```
60
+
61
+ ## API
62
+
63
+ ### `MockServerContainer(image=..., port=1080)`
64
+
65
+ - `image` — Docker image to use. Defaults to `mockserver/mockserver:mockserver-7.1.0`.
66
+ - `port` — Container port MockServer listens on. Defaults to `1080`.
67
+
68
+ ### Methods
69
+
70
+ | Method | Returns | Description |
71
+ |--------|---------|-------------|
72
+ | `get_url()` | `str` | HTTP base URL (e.g. `http://localhost:49152`) |
73
+ | `get_secure_url()` | `str` | HTTPS base URL (same port, `https://` scheme) |
74
+ | `get_host()` | `str` | Mapped host IP |
75
+ | `get_port()` | `int` | Mapped host port |
76
+ | `with_server_port(port)` | `self` | Override the listen port |
77
+ | `with_log_level(level)` | `self` | Set `MOCKSERVER_LOG_LEVEL` |
78
+ | `with_property(key, value)` | `self` | Set any MockServer env var |
79
+ | `with_initialization_json(path)` | `self` | Point to a startup expectations JSON file |
80
+
81
+ ## Building and Testing
82
+
83
+ ```bash
84
+ # Install in editable mode with test dependencies
85
+ pip install -e .[test]
86
+
87
+ # Run unit tests (no Docker needed)
88
+ pytest tests/test_container_config.py
89
+
90
+ # Run all tests including integration (requires Docker)
91
+ pytest
92
+
93
+ # Skip Docker-dependent tests
94
+ pytest -m "not docker"
95
+ ```
96
+
97
+ ## Requirements
98
+
99
+ - Python >= 3.9
100
+ - Docker (for integration tests and actual usage)
101
+ - `testcontainers` >= 4.0.0
@@ -0,0 +1,74 @@
1
+ # testcontainers-mockserver
2
+
3
+ A [Testcontainers](https://testcontainers.com) module for [MockServer](https://www.mock-server.com) in Python.
4
+
5
+ Starts a `mockserver/mockserver` Docker container, waits for readiness, and provides
6
+ convenient accessors for the mapped host, port, and URL.
7
+
8
+ ## Installation
9
+
10
+ ```bash
11
+ pip install testcontainers-mockserver
12
+ ```
13
+
14
+ ## Usage
15
+
16
+ ```python
17
+ from testcontainers_mockserver import MockServerContainer
18
+ import requests
19
+
20
+ with MockServerContainer() as mockserver:
21
+ url = mockserver.get_url() # e.g. "http://localhost:49152"
22
+
23
+ # Create an expectation
24
+ requests.put(f"{url}/mockserver/expectation", json={
25
+ "httpRequest": {"method": "GET", "path": "/hello"},
26
+ "httpResponse": {"statusCode": 200, "body": "world"},
27
+ })
28
+
29
+ # Match it
30
+ resp = requests.get(f"{url}/hello")
31
+ assert resp.text == "world"
32
+ ```
33
+
34
+ ## API
35
+
36
+ ### `MockServerContainer(image=..., port=1080)`
37
+
38
+ - `image` — Docker image to use. Defaults to `mockserver/mockserver:mockserver-7.1.0`.
39
+ - `port` — Container port MockServer listens on. Defaults to `1080`.
40
+
41
+ ### Methods
42
+
43
+ | Method | Returns | Description |
44
+ |--------|---------|-------------|
45
+ | `get_url()` | `str` | HTTP base URL (e.g. `http://localhost:49152`) |
46
+ | `get_secure_url()` | `str` | HTTPS base URL (same port, `https://` scheme) |
47
+ | `get_host()` | `str` | Mapped host IP |
48
+ | `get_port()` | `int` | Mapped host port |
49
+ | `with_server_port(port)` | `self` | Override the listen port |
50
+ | `with_log_level(level)` | `self` | Set `MOCKSERVER_LOG_LEVEL` |
51
+ | `with_property(key, value)` | `self` | Set any MockServer env var |
52
+ | `with_initialization_json(path)` | `self` | Point to a startup expectations JSON file |
53
+
54
+ ## Building and Testing
55
+
56
+ ```bash
57
+ # Install in editable mode with test dependencies
58
+ pip install -e .[test]
59
+
60
+ # Run unit tests (no Docker needed)
61
+ pytest tests/test_container_config.py
62
+
63
+ # Run all tests including integration (requires Docker)
64
+ pytest
65
+
66
+ # Skip Docker-dependent tests
67
+ pytest -m "not docker"
68
+ ```
69
+
70
+ ## Requirements
71
+
72
+ - Python >= 3.9
73
+ - Docker (for integration tests and actual usage)
74
+ - `testcontainers` >= 4.0.0
@@ -0,0 +1,50 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "testcontainers-mockserver"
7
+ version = "7.1.0"
8
+ description = "Testcontainers module for MockServer"
9
+ readme = "README.md"
10
+ license = "Apache-2.0"
11
+ requires-python = ">=3.9"
12
+ authors = [
13
+ { name = "James D Bloom", email = "jamesdbloom@gmail.com" },
14
+ ]
15
+ keywords = ["testing", "docker", "mockserver", "testcontainers", "mocking"]
16
+ classifiers = [
17
+ "Development Status :: 4 - Beta",
18
+ "Intended Audience :: Developers",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.9",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
+ "Programming Language :: Python :: 3.14",
26
+ "Topic :: Software Development :: Testing",
27
+ ]
28
+ dependencies = [
29
+ "testcontainers>=4.0.0",
30
+ ]
31
+
32
+ [project.optional-dependencies]
33
+ test = [
34
+ "pytest>=7.0",
35
+ "requests>=2.20",
36
+ ]
37
+
38
+ [project.urls]
39
+ Homepage = "https://www.mock-server.com"
40
+ Repository = "https://github.com/mock-server/mockserver"
41
+ Documentation = "https://www.mock-server.com/mock_server/mockserver_testcontainers.html"
42
+
43
+ [tool.setuptools.packages.find]
44
+ where = ["src"]
45
+
46
+ [tool.pytest.ini_options]
47
+ testpaths = ["tests"]
48
+ markers = [
49
+ "docker: marks tests that require a running Docker daemon (deselect with '-m \"not docker\"')",
50
+ ]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,20 @@
1
+ """Testcontainers module for MockServer.
2
+
3
+ Provides a ``MockServerContainer`` that starts a ``mockserver/mockserver`` Docker
4
+ image, waits for readiness, and exposes convenience accessors for the mapped
5
+ host, port, and base URL.
6
+
7
+ Example::
8
+
9
+ from testcontainers_mockserver import MockServerContainer
10
+
11
+ with MockServerContainer() as mockserver:
12
+ url = mockserver.get_url()
13
+ # url is e.g. "http://localhost:49152"
14
+ # Use requests or any HTTP client to interact with MockServer at this URL.
15
+ """
16
+
17
+ from testcontainers_mockserver.container import MockServerContainer
18
+
19
+ __all__ = ["MockServerContainer"]
20
+ __version__ = "7.0.0"
@@ -0,0 +1,139 @@
1
+ """MockServerContainer — Testcontainers module for MockServer.
2
+
3
+ This module provides a thin wrapper around testcontainers' ``DockerContainer`` that
4
+ starts a ``mockserver/mockserver`` image, waits for readiness via the
5
+ ``/mockserver/status`` HTTP endpoint (PUT, returns 200), and exposes convenience
6
+ methods for the mapped host, port, and URL.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from typing import Optional
12
+
13
+ from testcontainers.core.container import DockerContainer
14
+ from testcontainers.core.wait_strategies import HttpWaitStrategy
15
+
16
+ #: Default port MockServer listens on inside the container (HTTP, HTTPS, SOCKS,
17
+ #: and HTTP CONNECT all served on this single unified port).
18
+ MOCKSERVER_PORT = 1080
19
+
20
+ #: Default Docker image name for MockServer.
21
+ _IMAGE_NAME = "mockserver/mockserver"
22
+
23
+ #: Default image tag, pinned to the current MockServer release version.
24
+ _DEFAULT_TAG = "mockserver-7.0.0"
25
+
26
+
27
+ class MockServerContainer(DockerContainer):
28
+ """A Testcontainers wrapper that starts a MockServer Docker container.
29
+
30
+ The container starts the ``mockserver/mockserver`` image on port 1080 and waits
31
+ for the ``PUT /mockserver/status`` endpoint to return HTTP 200 before yielding
32
+ control.
33
+
34
+ Parameters
35
+ ----------
36
+ image : str, optional
37
+ Full Docker image reference. Defaults to
38
+ ``mockserver/mockserver:mockserver-7.0.0``.
39
+ port : int, optional
40
+ The port MockServer listens on inside the container. Defaults to 1080.
41
+
42
+ Example
43
+ -------
44
+ ::
45
+
46
+ from testcontainers_mockserver import MockServerContainer
47
+
48
+ with MockServerContainer() as server:
49
+ url = server.get_url()
50
+ # e.g. "http://localhost:49152"
51
+ """
52
+
53
+ def __init__(
54
+ self,
55
+ image: str = f"{_IMAGE_NAME}:{_DEFAULT_TAG}",
56
+ port: int = MOCKSERVER_PORT,
57
+ **kwargs,
58
+ ) -> None:
59
+ super().__init__(image=image, **kwargs)
60
+ self._port = port
61
+ self.with_exposed_ports(self._port)
62
+ self.with_env("SERVER_PORT", str(self._port))
63
+
64
+ def _build_wait_strategy(self) -> HttpWaitStrategy:
65
+ """Build the readiness wait strategy.
66
+
67
+ MockServer's ``/mockserver/status`` endpoint requires a PUT request and
68
+ returns HTTP 200 with a JSON body containing ``{ "ports": [...] }`` when
69
+ the server is ready.
70
+ """
71
+ return (
72
+ HttpWaitStrategy(self._port, "/mockserver/status")
73
+ .with_method("PUT")
74
+ .with_startup_timeout(60)
75
+ )
76
+
77
+ def start(self) -> "MockServerContainer":
78
+ """Start the container and wait for MockServer to become ready."""
79
+ super().start()
80
+ self._build_wait_strategy().wait_until_ready(self)
81
+ return self
82
+
83
+ # ------------------------------------------------------------------
84
+ # Convenience accessors
85
+ # ------------------------------------------------------------------
86
+
87
+ def get_host(self) -> str:
88
+ """Return the host IP to connect to MockServer from the test process."""
89
+ return self.get_container_host_ip()
90
+
91
+ def get_port(self) -> int:
92
+ """Return the mapped host port for MockServer's container port."""
93
+ return int(self.get_exposed_port(self._port))
94
+
95
+ def get_url(self) -> str:
96
+ """Return the HTTP base URL for MockServer (e.g. ``http://localhost:49152``)."""
97
+ return f"http://{self.get_host()}:{self.get_port()}"
98
+
99
+ def get_secure_url(self) -> str:
100
+ """Return the HTTPS base URL for MockServer (same port, different scheme)."""
101
+ return f"https://{self.get_host()}:{self.get_port()}"
102
+
103
+ # ------------------------------------------------------------------
104
+ # Configuration helpers (fluent)
105
+ # ------------------------------------------------------------------
106
+
107
+ def with_server_port(self, port: int) -> "MockServerContainer":
108
+ """Override the MockServer listen port inside the container.
109
+
110
+ This replaces the exposed port so the wait strategy targets the correct port.
111
+ """
112
+ self._port = port
113
+ # Reset exposed ports to only the new port
114
+ self.ports = {}
115
+ self.with_exposed_ports(port)
116
+ self.with_env("SERVER_PORT", str(port))
117
+ return self
118
+
119
+ def with_log_level(self, level: str) -> "MockServerContainer":
120
+ """Set the MockServer log level (e.g. INFO, DEBUG, WARN, ERROR, TRACE)."""
121
+ self.with_env("MOCKSERVER_LOG_LEVEL", level)
122
+ return self
123
+
124
+ def with_property(self, key: str, value: str) -> "MockServerContainer":
125
+ """Set a MockServer configuration property as an environment variable.
126
+
127
+ The key must be in MockServer env-var form (e.g. ``MOCKSERVER_LOG_LEVEL``).
128
+ """
129
+ self.with_env(key, value)
130
+ return self
131
+
132
+ def with_initialization_json(self, container_path: str) -> "MockServerContainer":
133
+ """Configure MockServer to load expectations from a JSON file at startup.
134
+
135
+ The file must already be mounted/copied into the container at *container_path*.
136
+ This sets the ``MOCKSERVER_INITIALIZATION_JSON_PATH`` environment variable.
137
+ """
138
+ self.with_env("MOCKSERVER_INITIALIZATION_JSON_PATH", container_path)
139
+ return self
@@ -0,0 +1,101 @@
1
+ Metadata-Version: 2.4
2
+ Name: testcontainers-mockserver
3
+ Version: 7.1.0
4
+ Summary: Testcontainers module for MockServer
5
+ Author-email: James D Bloom <jamesdbloom@gmail.com>
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://www.mock-server.com
8
+ Project-URL: Repository, https://github.com/mock-server/mockserver
9
+ Project-URL: Documentation, https://www.mock-server.com/mock_server/mockserver_testcontainers.html
10
+ Keywords: testing,docker,mockserver,testcontainers,mocking
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Topic :: Software Development :: Testing
21
+ Requires-Python: >=3.9
22
+ Description-Content-Type: text/markdown
23
+ Requires-Dist: testcontainers>=4.0.0
24
+ Provides-Extra: test
25
+ Requires-Dist: pytest>=7.0; extra == "test"
26
+ Requires-Dist: requests>=2.20; extra == "test"
27
+
28
+ # testcontainers-mockserver
29
+
30
+ A [Testcontainers](https://testcontainers.com) module for [MockServer](https://www.mock-server.com) in Python.
31
+
32
+ Starts a `mockserver/mockserver` Docker container, waits for readiness, and provides
33
+ convenient accessors for the mapped host, port, and URL.
34
+
35
+ ## Installation
36
+
37
+ ```bash
38
+ pip install testcontainers-mockserver
39
+ ```
40
+
41
+ ## Usage
42
+
43
+ ```python
44
+ from testcontainers_mockserver import MockServerContainer
45
+ import requests
46
+
47
+ with MockServerContainer() as mockserver:
48
+ url = mockserver.get_url() # e.g. "http://localhost:49152"
49
+
50
+ # Create an expectation
51
+ requests.put(f"{url}/mockserver/expectation", json={
52
+ "httpRequest": {"method": "GET", "path": "/hello"},
53
+ "httpResponse": {"statusCode": 200, "body": "world"},
54
+ })
55
+
56
+ # Match it
57
+ resp = requests.get(f"{url}/hello")
58
+ assert resp.text == "world"
59
+ ```
60
+
61
+ ## API
62
+
63
+ ### `MockServerContainer(image=..., port=1080)`
64
+
65
+ - `image` — Docker image to use. Defaults to `mockserver/mockserver:mockserver-7.1.0`.
66
+ - `port` — Container port MockServer listens on. Defaults to `1080`.
67
+
68
+ ### Methods
69
+
70
+ | Method | Returns | Description |
71
+ |--------|---------|-------------|
72
+ | `get_url()` | `str` | HTTP base URL (e.g. `http://localhost:49152`) |
73
+ | `get_secure_url()` | `str` | HTTPS base URL (same port, `https://` scheme) |
74
+ | `get_host()` | `str` | Mapped host IP |
75
+ | `get_port()` | `int` | Mapped host port |
76
+ | `with_server_port(port)` | `self` | Override the listen port |
77
+ | `with_log_level(level)` | `self` | Set `MOCKSERVER_LOG_LEVEL` |
78
+ | `with_property(key, value)` | `self` | Set any MockServer env var |
79
+ | `with_initialization_json(path)` | `self` | Point to a startup expectations JSON file |
80
+
81
+ ## Building and Testing
82
+
83
+ ```bash
84
+ # Install in editable mode with test dependencies
85
+ pip install -e .[test]
86
+
87
+ # Run unit tests (no Docker needed)
88
+ pytest tests/test_container_config.py
89
+
90
+ # Run all tests including integration (requires Docker)
91
+ pytest
92
+
93
+ # Skip Docker-dependent tests
94
+ pytest -m "not docker"
95
+ ```
96
+
97
+ ## Requirements
98
+
99
+ - Python >= 3.9
100
+ - Docker (for integration tests and actual usage)
101
+ - `testcontainers` >= 4.0.0
@@ -0,0 +1,11 @@
1
+ README.md
2
+ pyproject.toml
3
+ src/testcontainers_mockserver/__init__.py
4
+ src/testcontainers_mockserver/container.py
5
+ src/testcontainers_mockserver.egg-info/PKG-INFO
6
+ src/testcontainers_mockserver.egg-info/SOURCES.txt
7
+ src/testcontainers_mockserver.egg-info/dependency_links.txt
8
+ src/testcontainers_mockserver.egg-info/requires.txt
9
+ src/testcontainers_mockserver.egg-info/top_level.txt
10
+ tests/test_container_config.py
11
+ tests/test_integration.py
@@ -0,0 +1,5 @@
1
+ testcontainers>=4.0.0
2
+
3
+ [test]
4
+ pytest>=7.0
5
+ requests>=2.20
@@ -0,0 +1,188 @@
1
+ """Unit tests for MockServerContainer configuration.
2
+
3
+ These tests verify container configuration WITHOUT starting Docker.
4
+ They test URL shaping, environment variable setup, and port configuration.
5
+ """
6
+
7
+ import pytest
8
+
9
+ from testcontainers_mockserver import MockServerContainer
10
+ from testcontainers_mockserver.container import MOCKSERVER_PORT, _DEFAULT_TAG, _IMAGE_NAME
11
+
12
+
13
+ class TestDefaultConfiguration:
14
+ """Tests for default container configuration (no Docker needed)."""
15
+
16
+ def test_default_image(self):
17
+ container = MockServerContainer()
18
+ assert container.image == f"{_IMAGE_NAME}:{_DEFAULT_TAG}"
19
+
20
+ def test_default_port_constant(self):
21
+ assert MOCKSERVER_PORT == 1080
22
+
23
+ def test_default_exposes_port_1080(self):
24
+ container = MockServerContainer()
25
+ # The ports dict keys are the container ports
26
+ assert MOCKSERVER_PORT in container.ports
27
+
28
+ def test_default_sets_server_port_env(self):
29
+ container = MockServerContainer()
30
+ assert container.env["SERVER_PORT"] == "1080"
31
+
32
+ def test_custom_image(self):
33
+ container = MockServerContainer(image="mockserver/mockserver:latest")
34
+ assert container.image == "mockserver/mockserver:latest"
35
+
36
+ def test_custom_port(self):
37
+ container = MockServerContainer(port=9090)
38
+ assert 9090 in container.ports
39
+ assert container.env["SERVER_PORT"] == "9090"
40
+
41
+
42
+ class TestWithServerPort:
43
+ """Tests for with_server_port fluent method."""
44
+
45
+ def test_sets_env_and_port(self):
46
+ container = MockServerContainer()
47
+ result = container.with_server_port(9090)
48
+
49
+ assert result is container # fluent return
50
+ assert container.env["SERVER_PORT"] == "9090"
51
+ assert 9090 in container.ports
52
+
53
+ def test_replaces_default_port(self):
54
+ container = MockServerContainer()
55
+ container.with_server_port(9090)
56
+
57
+ # Default port 1080 should no longer be exposed
58
+ assert MOCKSERVER_PORT not in container.ports
59
+ assert 9090 in container.ports
60
+
61
+
62
+ class TestWithLogLevel:
63
+ """Tests for with_log_level fluent method."""
64
+
65
+ def test_sets_log_level_env(self):
66
+ container = MockServerContainer()
67
+ result = container.with_log_level("DEBUG")
68
+
69
+ assert result is container
70
+ assert container.env["MOCKSERVER_LOG_LEVEL"] == "DEBUG"
71
+
72
+
73
+ class TestWithProperty:
74
+ """Tests for with_property fluent method."""
75
+
76
+ def test_sets_arbitrary_env(self):
77
+ container = MockServerContainer()
78
+ result = container.with_property("MOCKSERVER_MAX_EXPECTATIONS", "500")
79
+
80
+ assert result is container
81
+ assert container.env["MOCKSERVER_MAX_EXPECTATIONS"] == "500"
82
+
83
+
84
+ class TestWithInitializationJson:
85
+ """Tests for with_initialization_json fluent method."""
86
+
87
+ def test_sets_initialization_json_path_env(self):
88
+ container = MockServerContainer()
89
+ result = container.with_initialization_json("/config/init.json")
90
+
91
+ assert result is container
92
+ assert container.env["MOCKSERVER_INITIALIZATION_JSON_PATH"] == "/config/init.json"
93
+
94
+
95
+ class TestFluentChaining:
96
+ """Tests for method chaining across multiple fluent helpers."""
97
+
98
+ def test_chain_multiple_methods(self):
99
+ container = MockServerContainer()
100
+ result = (
101
+ container
102
+ .with_log_level("WARN")
103
+ .with_server_port(8080)
104
+ .with_property("MOCKSERVER_MAX_EXPECTATIONS", "100")
105
+ )
106
+
107
+ assert result is container
108
+ assert container.env["MOCKSERVER_LOG_LEVEL"] == "WARN"
109
+ assert container.env["SERVER_PORT"] == "8080"
110
+ assert container.env["MOCKSERVER_MAX_EXPECTATIONS"] == "100"
111
+ assert 8080 in container.ports
112
+
113
+
114
+ class TestUrlShaping:
115
+ """Tests for URL/host/port accessors.
116
+
117
+ These test the URL construction logic by mocking the underlying testcontainers
118
+ methods that require a running container.
119
+ """
120
+
121
+ def test_get_url_format(self):
122
+ """Verify get_url produces the correct format when host and port are known."""
123
+ container = MockServerContainer()
124
+ # Monkey-patch the methods that need Docker
125
+ container.get_container_host_ip = lambda: "127.0.0.1"
126
+ container.get_exposed_port = lambda port: 49152
127
+
128
+ url = container.get_url()
129
+ assert url == "http://127.0.0.1:49152"
130
+
131
+ def test_get_secure_url_format(self):
132
+ """Verify get_secure_url uses https scheme."""
133
+ container = MockServerContainer()
134
+ container.get_container_host_ip = lambda: "localhost"
135
+ container.get_exposed_port = lambda port: 55000
136
+
137
+ url = container.get_secure_url()
138
+ assert url == "https://localhost:55000"
139
+
140
+ def test_get_host_delegates(self):
141
+ """Verify get_host delegates to get_container_host_ip."""
142
+ container = MockServerContainer()
143
+ container.get_container_host_ip = lambda: "192.168.1.100"
144
+
145
+ assert container.get_host() == "192.168.1.100"
146
+
147
+ def test_get_port_delegates(self):
148
+ """Verify get_port delegates to get_exposed_port with the configured port."""
149
+ container = MockServerContainer()
150
+ container.get_exposed_port = lambda port: 32768
151
+
152
+ assert container.get_port() == 32768
153
+
154
+ def test_get_port_respects_custom_port(self):
155
+ """Verify get_port uses the custom server port when configured."""
156
+ container = MockServerContainer(port=9090)
157
+
158
+ called_with = []
159
+ container.get_exposed_port = lambda port: (called_with.append(port), 32768)[1]
160
+
161
+ container.get_port()
162
+ assert called_with == [9090]
163
+
164
+ def test_get_url_with_custom_port(self):
165
+ """Verify get_url works correctly after with_server_port."""
166
+ container = MockServerContainer()
167
+ container.with_server_port(9090)
168
+ container.get_container_host_ip = lambda: "localhost"
169
+
170
+ called_with = []
171
+ container.get_exposed_port = lambda port: (called_with.append(port), 45000)[1]
172
+
173
+ url = container.get_url()
174
+ assert url == "http://localhost:45000"
175
+ assert called_with == [9090]
176
+
177
+
178
+ class TestVersionPinning:
179
+ """Tests that verify the version is correctly pinned."""
180
+
181
+ def test_default_tag_matches_release_version(self):
182
+ """The default tag must match the current MockServer release."""
183
+ assert _DEFAULT_TAG == "mockserver-7.0.0"
184
+
185
+ def test_module_version(self):
186
+ """The package version must match the MockServer release."""
187
+ import testcontainers_mockserver
188
+ assert testcontainers_mockserver.__version__ == "7.0.0"
@@ -0,0 +1,105 @@
1
+ """Integration tests for MockServerContainer.
2
+
3
+ These tests require a running Docker daemon. They are skipped when Docker is
4
+ unavailable, mirroring the Java repo's assumeTrue(isDockerAvailable()) convention.
5
+ """
6
+
7
+ import pytest
8
+
9
+ docker_available = False
10
+ try:
11
+ import docker
12
+
13
+ client = docker.from_env()
14
+ client.ping()
15
+ docker_available = True
16
+ except Exception:
17
+ pass
18
+
19
+ pytestmark = pytest.mark.docker
20
+
21
+
22
+ @pytest.fixture(scope="module")
23
+ def mockserver():
24
+ """Start a MockServer container for the module's integration tests."""
25
+ if not docker_available:
26
+ pytest.skip("Docker is not available")
27
+
28
+ from testcontainers_mockserver import MockServerContainer
29
+
30
+ with MockServerContainer() as container:
31
+ yield container
32
+
33
+
34
+ def test_container_starts_and_is_reachable(mockserver):
35
+ """Verify the container starts and the /mockserver/status endpoint responds."""
36
+ import requests
37
+
38
+ url = mockserver.get_url()
39
+ assert url.startswith("http://")
40
+
41
+ # MockServer's status endpoint is PUT-only
42
+ response = requests.put(f"{url}/mockserver/status")
43
+ assert response.status_code == 200
44
+
45
+ body = response.json()
46
+ assert "ports" in body
47
+
48
+
49
+ def test_get_host_returns_non_empty(mockserver):
50
+ """Verify get_host returns a non-empty string."""
51
+ host = mockserver.get_host()
52
+ assert host
53
+ assert isinstance(host, str)
54
+
55
+
56
+ def test_get_port_returns_positive_int(mockserver):
57
+ """Verify get_port returns a positive integer."""
58
+ port = mockserver.get_port()
59
+ assert isinstance(port, int)
60
+ assert port > 0
61
+
62
+
63
+ def test_expectation_lifecycle(mockserver):
64
+ """Verify a basic create-expectation/match/verify lifecycle."""
65
+ import json
66
+
67
+ import requests
68
+
69
+ url = mockserver.get_url()
70
+
71
+ # Create an expectation
72
+ expectation = {
73
+ "httpRequest": {
74
+ "method": "GET",
75
+ "path": "/hello",
76
+ },
77
+ "httpResponse": {
78
+ "statusCode": 200,
79
+ "body": "world",
80
+ },
81
+ }
82
+ resp = requests.put(f"{url}/mockserver/expectation", json=expectation)
83
+ assert resp.status_code == 201
84
+
85
+ # Match the expectation
86
+ resp = requests.get(f"{url}/hello")
87
+ assert resp.status_code == 200
88
+ assert resp.text == "world"
89
+
90
+ # Verify the request was received
91
+ verify_body = {
92
+ "httpRequest": {
93
+ "method": "GET",
94
+ "path": "/hello",
95
+ },
96
+ "times": {
97
+ "atLeast": 1,
98
+ },
99
+ }
100
+ resp = requests.put(f"{url}/mockserver/verify", json=verify_body)
101
+ assert resp.status_code == 202
102
+
103
+ # Reset
104
+ resp = requests.put(f"{url}/mockserver/reset")
105
+ assert resp.status_code == 200