4

I'd like to patch some elisp functions inside my unit tests. I've tried cl-labels and cl-flet, but neither achieve the result I want:

(defun return-number ()
  1)

(defun calls-return-number ()
  (return-number))

(defun patch-cl-labels ()
  (cl-labels ((return-number () 2))
    (calls-return-number)))

(message "After patching: %s" (patch-cl-labels))

I've looked at monkey-patching a function (but this permanently changes behaviour) and patching a third-party function (this uses advice and holds on to the old function).

3
  • "neither achieve the result I want" - which is not specified here. The question is too broad and unclear.
    – Drew
    Commented Aug 4, 2016 at 1:39
  • What I want is specified in the title: I want to temporarily mock a function. In the example, I want return-number to return 2. Commented Aug 5, 2016 at 17:36
  • As I said, you do not say how your attempts do not achieve the result you want. Clearly, if all you want is for "return-number to return 2" then (defun return-number () 2) achieves that. And as for temporary, just save the original definition (see symbol-function) and later restore it (see fset or defalias). I sense that you want something more or different, but you don't specify what that is.
    – Drew
    Commented Aug 5, 2016 at 18:00

1 Answer 1

7

Both macros are lexically scoped, that's why they have no effect on the "distant" call. Either use the deprecated older flet or cl-letf.

(cl-letf (((symbol-function 'return-number)
           (lambda () 2)))
  ...)
2
  • Of course, I was confusing with dynamic scope. Thanks. Commented Aug 6, 2016 at 14:00
  • Doom has a macro wrapper aroundcl-letf named letf!.
    – HappyFace
    Commented Sep 19, 2021 at 8:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.