16
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

プライベート関数をユニットテストする

Last updated at Posted at 2014-12-22

アクセス制御を回避して、プライベート関数をテストする方法

プライベート関数をVarに変換してアクセスすれば、他のパッケージから呼び出し可能。参考

  • プライベート関数を定義
(ns private-test.core)

(defn- a-private-func []
  (println "called a private function."))
  • ユニットテストから呼び出し
(ns private-test.core-test
  (:require [expectations :refer :all]
            [private-test.core :refer :all]))

(expect nil
  (a-private-func))
Error refreshing environment: java.lang.RuntimeException: Unable to resolve symbol: a-private-func in this context, compiling:(private_test/core_test.clj:6:3)
  • 完全パッケージ名をつけても同様に失敗
(expect nil
  (private-test.core/a-private-func))
  • #' をつけると、異なる名前空間からでもプライベート関数の呼び出しが可能
(expect nil
  (#'private-test.core/a-private-func))

なぜこんなことが可能なのか

  • #' (Var quote)は(var x)の省略記法。private-test.core/a-private-funcはシンボル(clojure.lang.Symbol)であるが、Var quoteによってvar (clojure.lang.Var)に変換されている。プライベート関数のアクセス制限はシンボル内の:privateメタデータで行われているため、varに変換されるとその制限は外れる。
(meta #'private-test.core/a-private-func)
=>
{:private true, :ns #<Namespace private-test.core>, :name a-private-func, :file "private_test/core.clj", :column 1, :line 3, :arglists ([])}
16
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?