test(visualization): isolate optional dependency mocks (#897)

* test(visualization): isolate optional dependency mocks

* test(visualization): stop requiring Plotly in unit tests

Removing the global sys.modules stubs left the tests that patch
`...go.Bar`, or call a visualizer, with nothing standing in for the
module level `px` and `go` aliases. Those are None when Plotly is
missing, so patch resolution and _check_dependencies() both failed.

Add a helper that substitutes a double only for the aliases that are
None, leaving the real module in place when Plotly is installed.

---------
This commit is contained in:
Luan Taraschi
2026-08-20 17:58:20 +05:00
committed by GitHub
parent 54c274e02c
commit c5d382ee81
7 changed files with 187 additions and 245 deletions
+29
View File
@@ -0,0 +1,29 @@
"""Shared helper for visualization tests.
The visualization modules treat Plotly as optional: they bind ``px``, ``go`` and
``make_subplots`` to ``None`` when the import fails, and raise ``ProcessingError``
from ``_check_dependencies()``. Tests that exercise a Plotly-backed path need
those names to be usable, otherwise ``patch("...go.Figure")`` fails on ``None``
and the visualizers refuse to run.
``plotly_doubles`` fills in a double for each alias that is ``None``, so the
tests describe their own requirements instead of depending on whether Plotly
happens to be installed. When Plotly is installed the aliases are left alone and
the patches keep asserting against the real attribute names.
"""
from contextlib import ExitStack, contextmanager
from unittest.mock import MagicMock, patch
PLOTLY_ALIASES = ("px", "go", "make_subplots")
@contextmanager
def plotly_doubles(*modules):
"""Stand in for the module-level Plotly aliases that are unavailable."""
with ExitStack() as stack:
for module in modules:
for alias in PLOTLY_ALIASES:
if getattr(module, alias, "unused") is None:
stack.enter_context(patch.object(module, alias, MagicMock()))
yield