3

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).

Drew
  • 77,472
  • 10
  • 114
  • 243
Wilfred Hughes
  • 6,920
  • 2
  • 31
  • 60
  • "neither achieve the result I want" - which is not specified here. The question is too broad and unclear. – Drew Aug 04 '16 at 01: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. – Wilfred Hughes Aug 05 '16 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 Aug 05 '16 at 18:00

1 Answers1

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)))
  ...)
politza
  • 3,336
  • 16
  • 16