Repository: sktime/sktime

Issue:
[ENH] `make_mock_estimator` should allow passing constructor args for the mocked class
**Describe the bug**
<!--
A clear and concise description of what the bug is.
-->
The current implementation of `sktime.utils.estimators.make_mock_estimator` does not allow to pass any arguments to the returned Mock Estimator Class `__init__`. As a result, we can only use it to reproduce the behaviour of the estimator class with it's default arguments.

**To Reproduce**
<!--
Add a Minimal, Complete, and Verifiable example (for more details, see e.g. https://stackoverflow.com/help/mcve

If the code is too long, feel free to put it in a public gist and link it in the issue: https://gist.github.com
-->

```python
from sktime.forecasting.naive import NaiveForecaster
from sktime.utils.estimators import make_mock_estimator
from sktime.datasets import load_airline
y = load_airline()
mock_estimator_class = make_mock_estimator(NaiveForecaster)
mock_estimator_instance = mock_estimator_class(strategy=last, sp=1})
```

**Expected behavior**
<!--
A clear and concise description of what you expected to happen.
-->
There should be a way to pass the __init__ arguments of the input estimator class to the mock estimator.



Discussion:

Resolving patch:
diff --git a/sktime/utils/estimators/_base.py b/sktime/utils/estimators/_base.py
--- a/sktime/utils/estimators/_base.py
+++ b/sktime/utils/estimators/_base.py
@@ -56,6 +56,9 @@ def make_mock_estimator(
 ) -> BaseEstimator:
     r"""Transform any estimator class into a mock estimator class.
 
+    The returned class will accept the original arguments passed in estimator_class
+    __init__ as a dictionary of kwargs.
+
     Parameters
     ----------
     estimator_class : BaseEstimator
@@ -71,12 +74,28 @@ def make_mock_estimator(
     -------
     BaseEstimator
         input estimator class with logging feature enabled
+
+    Examples
+    --------
+    >>> from sktime.forecasting.naive import NaiveForecaster
+    >>> from sktime.utils.estimators import make_mock_estimator
+    >>> from sktime.datasets import load_airline
+    >>> y = load_airline()
+    >>> mock_estimator_class = make_mock_estimator(NaiveForecaster)
+    >>> mock_estimator_instance = mock_estimator_class({"strategy": "last", "sp": 1})
+    >>> mock_estimator_instance.fit(y)
+    _MockEstimator(...)
+
     """
     dunder_methods_regex = r"^__\w+__$"
 
     class _MockEstimator(estimator_class, _MockEstimatorMixin):
-        def __init__(self):
-            super().__init__()
+        def __init__(self, estimator_kwargs=None):
+            self.estimator_kwargs = estimator_kwargs
+            if estimator_kwargs is not None:
+                super().__init__(**estimator_kwargs)
+            else:
+                super().__init__()
 
     for attr_name in dir(estimator_class):
         attr = getattr(_MockEstimator, attr_name)


Test patch:
diff --git a/sktime/utils/estimators/tests/test_base.py b/sktime/utils/estimators/tests/test_base.py
--- a/sktime/utils/estimators/tests/test_base.py
+++ b/sktime/utils/estimators/tests/test_base.py
@@ -4,6 +4,7 @@
 __author__ = ["ltsaprounis"]
 
 import pytest
+from pandas.testing import assert_series_equal
 
 from sktime.classification.base import BaseClassifier
 from sktime.clustering.base import BaseClusterer
@@ -159,3 +160,29 @@ def test_make_mock_estimator(estimator_class, method_regex, logged_methods):
     methods_called = [entry[0] for entry in estimator.log]
 
     assert set(methods_called) >= set(logged_methods)
+
+
+@pytest.mark.parametrize(
+    "estimator_class, estimator_kwargs",
+    [
+        (NaiveForecaster, {"strategy": "last", "sp": 2, "window_length": None}),
+        (NaiveForecaster, {"strategy": "mean", "sp": 1, "window_length": None}),
+    ],
+)
+def test_make_mock_estimator_with_kwargs(estimator_class, estimator_kwargs):
+    """Test that make_mock_estimator behaves like the passed estimator."""
+    mock_estimator = make_mock_estimator(estimator_class)
+    mock_estimator_instance = mock_estimator(estimator_kwargs)
+    estimator_instance = estimator_class(**estimator_kwargs)
+    mock_estimator_instance.fit(y_series)
+    estimator_instance.fit(y_series)
+
+    assert_series_equal(
+        estimator_instance.predict(fh=[1, 2, 3]),
+        mock_estimator_instance.predict(fh=[1, 2, 3]),
+    )
+    assert (
+        (mock_estimator_instance.strategy == estimator_kwargs["strategy"])
+        and (mock_estimator_instance.sp == estimator_kwargs["sp"])
+        and (mock_estimator_instance.window_length == estimator_kwargs["window_length"])
+    )