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
  • 75,699
  • 9
  • 109
  • 225
Wilfred Hughes
  • 6,890
  • 2
  • 29
  • 59
  • "*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,316
  • 14
  • 16