How to temporarily change the definition of a function?
Calling a function by its (symbol) name means calling that symbol's function slot. So, to temporarily change the definition of a function that is called by its name, you need to temporarily modify its symbol-function value. The shortest way to do that is with cl-letf; see (info "(cl) Modify Macros").
(eval-when-compile (require 'cl-lib)) (defun f2 () (message "outer f2")) (defun foo () (f2)) (cl-letf (((symbol-function 'f2) (lambda () (message "inner f2")))) (foo)) ;; => inner f2
An alternative, more compositional approach is to use function advice, but to my knowledge there isn't a handy macro for that, and it doesn't provide any benefits in simple cases like the example above. For example:
(unwind-protect (progn (advice-add 'f2 :override (lambda () (message "inner f2")) '((name . my-override))) (foo)) (advice-remove 'f2 'my-override)) ;; => inner f2