Dhia Shalabi
Dhia Shalabi

Reputation: 1540

RuntimeError: object is not bound when running Frappe unittest with pytest

I'm trying to implement a unittest for a Frappe Doctype without using the FrappeTestCase class. My implementation works fine when running tests with the bench run-tests command but fails with pytest. Here is my Doctype and unittest implementation.

NOTES:

  1. I want to run the test with the pytest not using the bench command.
  2. Using the bench run-tests command is working but using pytest is not.
  3. Running the tests with python -m unittest also gives the same error.

Doctype Implementation:

class FeedbackClassification(Document):
    def validate(self):
        self.validate_classification_code()

    def validate_classification_code(self):
        if frappe.db.exists(
            "Feedback Classification", {"classification_code": self.classification_code, "name": ("!=", self.name)}
        ):
            frappe.throw(
                _("Duplicate classification codes {0} already exists").format(frappe.bold(self.classification_code)),
                title=_("Duplicate Classification Code"),
                exc=frappe.UniqueValidationError,
            )

Unittest Implementation:

class TestFeedbackClassification(unittest.TestCase):
    def setUp(self):
        with patch.object(FeedbackClassification, "__init__", lambda x: None):
            self.mock_feedback_classification = FeedbackClassification()

        patcher = patch(
            "frappe.throw", side_effect=lambda *args, **kwargs: (_ for _ in ()).throw(UniqueValidationError(args[0]))
        )
        self.mock_throw = patcher.start()
        self.addCleanup(patcher.stop)

        self.mock_feedback_classification.classification_code = None
        self.mock_feedback_classification.name = "Test Classification"

    def set_classification_code(self, classification_code):
        self.mock_feedback_classification.classification_code = classification_code

    @patch("frappe.db.exists")
    def test_validate_duplicate_classification_code(self, mock_exists):
        self.set_classification_code("Classification 1")
        mock_exists.return_value = True

        with self.assertRaises(UniqueValidationError) as cm:
            self.mock_feedback_classification.validate()

        expected_message = "Duplicate classification codes <strong>Classification 1</strong> already exists"
        self.assertIn(expected_message, str(cm.exception))

    @patch("frappe.db.exists")
    def test_validate_no_duplicate_classification_code(self, mock_exists):
        self.set_classification_code("Classification")
        mock_exists.return_value = False

        try:
            self.mock_feedback_classification.validate()
        except UniqueValidationError:
            self.fail("validate() raised UniqueValidationError unexpectedly!")

When running the test with pytest, I get the following error:

doctype/feedback_classification/test_feedback_classification.py::TestFeedbackClassification::test_validate_duplicate_classification_code failed: /usr/local/lib/python3.11/unittest/mock.py:1372: in patched
    with self.decoration_helper(patched,
/usr/local/lib/python3.11/contextlib.py:137: in __enter__
    return next(self.gen)
/usr/local/lib/python3.11/unittest/mock.py:1354: in decoration_helper
    arg = exit_stack.enter_context(patching)
/usr/local/lib/python3.11/contextlib.py:505: in enter_context
    result = _enter(cm)
/usr/local/lib/python3.11/unittest/mock.py:1443: in __enter__
    original, local = self.get_original()
/usr/local/lib/python3.11/unittest/mock.py:1406: in get_original
    original = target.__dict__[name]
frappe-bench/env/lib/python3.11/site-packages/werkzeug/local.py:311: in __get__
    obj = instance._get_current_object()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def _get_current_object() -> T:
        try:
            return get_name(local)  # type: ignore[return-value]
        except AttributeError:
>           raise RuntimeError(unbound_message) from None
E           RuntimeError: object is not bound

frappe-bench/env/lib/python3.11/site-packages/werkzeug/local.py:490: RuntimeError

What I Tried:

Expected Behavior:

Environment:

Upvotes: 0

Views: 112

Answers (0)

Related Questions