PhoenixとElixirを使用してブログエンジンを作成する/パート5. ExMachinaを接続する





翻訳者から:「 エリクサーとフェニックスは、最新のウェブ開発がどこに進んでいるかの良い例です。 すでにこれらのツールは、Webアプリケーションのリアルタイムテクノロジーへの質の高いアクセスを提供します。 対話性が向上したサイト、マルチユーザーブラウザーゲーム、マイクロサービスは、これらの技術がうまく機能する分野です。 以下は、Phoenixフレームワークでの開発の詳細な側面を説明する一連の11の記事の翻訳です。ブログエンジンのような些細なことのように思えます。 しかし、急いでつまずかないでください。特に記事がエリクサーに注意を払うか、彼のフォロワーになるように促す場合、それは本当に面白いでしょう。



この部分では、ExMachinaライブラリを含めて、テストプロセスを改善します。 テストしたモデルを作成するために同一のコードをコピーする必要はありません。工場が私たちのためにそれを行います!



現時点では、アプリケーションは以下に基づいています。





はじめに



お気づきのように、このエンジンを作成するプロセスでは、いくつかのライブラリのみを使用します。 次に、ExMachinaと呼ばれる別のものを追加します。 彼女は、RubyのFactory Girlに類似しています。



これは何?



前述のように、ExMachinaは、RubyのFactoryパターン(Thoughtbotのすばらしい人物による)の実装であるFactory Girlのイメージで設計されています。 コードを書き直さずにテストを作成することなく、リレーションシップを持つさまざまなモデルをテストに追加することは素晴らしいことです。 モデルを生成するための単純な関数を含む補助モジュールを使用して、同じことを自分で達成できます。 しかし、それはすべて、必要なデータセットごと、通信ごとなどに、そのようなモジュールを絶えず作成することに帰着します。 これには確かに退屈する時間があります。



降りる



mix.exs



mix.exs



ファイルを開いて、 deps



およびapplication



リストに追加します。 これを行うには、ExMachinaの別のエントリをComeOnInの直後の依存関係のリストに挿入します。



 defp deps do [{:phoenix, "~> 1.2.0"}, {:phoenix_pubsub, "~> 1.0"}, {:phoenix_ecto, "~> 3.0"}, {:postgrex, ">= 0.0.0"}, {:phoenix_html, "~> 2.6"}, {:phoenix_live_reload, "~> 1.0", only: :dev}, {:gettext, "~> 0.11"}, {:cowboy, "~> 1.0"}, {:comeonin, "~> 2.5.2"}, {:ex_machina, "~> 1.0"}] end
      
      





次に、使用されているアプリケーションのリストに:ex_machina



を追加します。



 def application do [mod: {Pxblog, []}, applications: [:phoenix, :phoenix_pubsub, :phoenix_html, :cowboy, :logger, :gettext, :phoenix_ecto, :postgrex, :comeonin, :ex_machina]] end
      
      





次のコマンドを実行して、アプリケーションコンポーネントの準備ができ、正しく構成されていることを確認します。



 $ mix do deps.get, compile
      
      





すべてがうまくいけば、ExMachinaのインストールとプロジェクトのコンパイルに関するメッセージが出力に表示されるはずです! コードの変更を開始する前に、 mix test



を実行し、信頼性を高めるために、すべてのテストがグリーンであることを確認する必要があります。



ロールの最初のファクトリーを追加します



ファクトリモジュールを作成し、すべてのテストで使用できるようにする必要があります。 私はテストを膨らませることなくこれを行うことを好みます。 これを行うには、ファクトリを含むモジュールファイルをtest/support



ディレクトリにドロップし、必要なテストでそのインポートを記述します。



それでは、ファイルtest/support/factory.ex



作成することから始めましょう:



 defmodule Pxblog.Factory do use ExMachina.Ecto, repo: Pxblog.Repo alias Pxblog.Role alias Pxblog.User alias Pxblog.Post def role_factory do %Role{ name: sequence(:name, &"Test Role #{&1}"), admin: false } end end
      
      





このような名前はこのモジュールの本質を反映しているため、これをFactory



と呼びました。 次に、特別なファクトリー関数を使用します。 これらは、入力に供給されたアトムをサンプルと比較し、 アセンブル / 作成するファクトリのタイプを決定します 。 このライブラリはFactory Girlに非常に近いため、知っておくべき重要な命名規則ももたらします。 最初のそのような名前はbuild



です。 build



機能とは、データベースに保存せずにモデル( リビジョンではなく)がbuild



ことを意味します。 2番目の規則は、 insert



関数の名前になります。反対に、モデルはデータベースに格納され、それによってモデルが作成されます。



また、ExMachinaがEctoをレポレイヤーとして使用し、モデル、関連付けなどの作成時にそれに応じて動作するように、ExMachina.Ectoの使用を指定use ExMachina.Ecto



必要があります。 また、ファクトリを作成するすべてのモデルにエイリアスを追加する必要があります。



role_factory



関数は、デフォルトのプロパティを定義するRole



構造を単に返す必要があります。 この関数は、アリティ1のみをサポートします。



sequence



機能を備えた作品は非常に興味深いものです。 ロールごとに一意の名前を生成する必要があります。 したがって、順次生成されます。 これを行うには、2つの引数を渡すsequence



関数を使用します。1つ目はシーケンスを生成するフィールドの名前で、2つ目は文字列を返し、その中の値を補間する匿名関数です。 この関数を見てみましょう:



 &”Test Role #{&1}”
      
      





Elixirに精通している場合は、匿名関数を記述する別の方法を学習している可能性があります。 これはおおよそ次のように変換されます。



 fn x -> "Test Role #{x}" end
      
      





したがって、 sequence



関数は次のように説明できます。



 sequence(:name, fn x -> "Test Role #{x}" end)
      
      





最後に、管理フラグをfalse



に設定しfalse



。 この値をデフォルト条件として使用します。 これを明示的に示すことにより、管理ロールを作成できます。 ExMachinaの他のより高度な機能については、少し後で説明します。 それでは、新しいRole



ファクトリとコントローラーテストを組み合わせて時間をかけてみましょう。



コントローラテストにロールファクトリを追加する



最初にファイルtest/controllers/user_controller_test.exs



開きます。 上部のsetup



ブロックで、新しいTestHelper.create_role



関数の使用を追加します。



 # ... import Pxblog.Factory @valid_create_attrs %{email: "test@test.com", username: "test", password: "test", password_confirmation: "test"} @valid_attrs %{email: "test@test.com", username: "test"} @invalid_attrs %{} setup do user_role = insert(:role) {:ok, nonadmin_user} = TestHelper.create_user(user_role, %{email: "nonadmin@test.com", username: "nonadmin", password: "test", password_confirmation: "test"}) admin_role = insert(:role, admin: true) {:ok, admin_user} = TestHelper.create_user(admin_role, %{email: "admin@test.com", username: "admin", password: "test", password_confirmation: "test"}) {:ok, conn: build_conn(), admin_role: admin_role, user_role: user_role, nonadmin_user: nonadmin_user, admin_user: admin_user} end # ...
      
      





ただし、その前に、ファクトリモジュール自体をインポートします。 10 行目で、 :role



ファクトリを使用してロールを追加します。 13行目でも同じことを行いますが、adminフラグをtrue



オーバーライドしtrue







ファイルを保存して、テストを再開します。 すべてがまだ合格しなければなりません! ここで、ユーザー用のファクトリを作成して、接続を作成します。



ユーザー用のファクトリーを追加する



ユーザー向けの工場をご覧ください。



 def user_factory do %User{ username: sequence(:username, &"User #{&1}"), email: "test@test.com", password: "test1234", password_confirmation: "test1234", password_digest: Comeonin.Bcrypt.hashpwsalt("test1234"), role: build(:role) } end
      
      





基本的に、このファクトリは、ロールを作成するために以前に記述したものと一致します。 しかし、対処しなければならない落とし穴がいくつかあります。 上記の7行目でpassword_digest



値をpassword_digest



ハッシュ値に設定していることがわかりpassword



(ユーザーログインをシミュレートしているため、これも追加する必要があります)。 ComeoninからBcryptモジュールを呼び出し、hashpwsalt関数を使用して、 password



/ password_confirmation



フィールドと同じ値を渡します。 次の行では、 role



を関連付けとして設定します。 build



関数を使用して、アトムの形でアセンブルしたい関連付けの名前を渡します。



ユーザーファクトリを変更したら、ファイルtest/controllers/user_controller_test.exs



に戻りましょう。



 setup do user_role = insert(:role) nonadmin_user = insert(:user, role: user_role) admin_role = insert(:role, admin: true) admin_user = insert(:user, role: admin_role) {:ok, conn: build_conn(), admin_role: admin_role, user_role: user_role, nonadmin_user: nonadmin_user, admin_user: admin_user} end
      
      





最後に、 TestHelper



へのすべての呼び出しをTestHelper



への呼び出しに置き換えます。 ロールを取得してファクトリーに転送し、正しいロールを持つユーザーを作成します。 その後、管理者と同じことを行いますが、テストを変更する必要はありません!



それらを実行し、それらがまだ緑色であることを確認します。 続けることができます。



投稿用の工場を追加する



私たちはすでに新しい工場を追加することに取り組んでいると思うので、後者の工場で作業することは問題を引き起こさないはずです。



ここには新しいものはないので、ファイルtest/controllers/post_controller_test.exs



変更してみましょう。



 def post_factory do %Post{ title: "Some Post", body: "And the body of some post", user: build(:user) } end
      
      





もう一度、 Pxblog.Factory



モジュールをimport



、呼び出しを行っているファクトリーの場所をテストで確認Pxblog.Factory



します。 次に、 setup



ブロックで投稿を作成するためのすべての手順をファクトリコールに置き換えます。 insert



関数を使用して、 role



構造が作成されます。この構造は、ファクトリを介してユーザーを作成するために使用され、最終的には、それに関連付けられた投稿を作成するために使用されます...



テストを実行します。 彼らは再び緑色になりました!



この場所から、他のすべてはただの余分な仕事です。 戻って、 TestHelper



へのすべての呼び出しをFactory



呼び出しに置き換えましょう。 これは特に新しいものでも刺激的なものでもないため、詳細の説明にはあまり注意を払いません。



工場を接続する他の方法



工場を各テストに明示的に接続するパスを選択しますが、同じことをしたくない場合は、次のいずれかの方法を使用できます。



ファイルtest/support/model_case.ex



using



ブロックにエイリアスを追加します。



 using do quote do alias Pxblog.Repo import Ecto import Ecto.Changeset import Ecto.Query import Pxblog.ModelCase import Pxblog.Factory end end
      
      





そして、ファイルtest/support/conn_case.ex







 using do quote do # Import conveniences for testing with connections use Phoenix.ConnTest alias Pxblog.Repo import Ecto import Ecto.Changeset import Ecto.Query import Pxblog.Router.Helpers import Pxblog.Factory # The default endpoint for testing @endpoint Pxblog.Endpoint end end
      
      





ExMachinaのその他の機能



小さなブログエンジンの目的のために、ExMachinaが提供する他の機能は必要ありません。 たとえば、 build



create



に加えて、利便性のためにいくつかの他の機能のサポートがありcreate



(例としてbuild



を使用build



ていますが、これはcreate



でも機能しcreate



)。



 build_pair(:factory, attrs) <- Builds 2 models build_list(n, :factory, attrs) <- Builds N models
      
      





build



メソッドをcreate



してcreate



したモデルを保存するには、 create



メソッドを呼び出しcreate







 build(:role) |> insert
      
      





その他の資料



ExMachinaの使用の詳細については、 Githubページをご覧ください 。 また、Thoughtbotの技術ブログにもアクセスできます。このブログでは、クリエイターがExMachina優れた発表やその他の使用方法を投稿しています。



まとめると



最初に、私は少し警戒心があり、以前ファクトリーガールの助けを借りていくつかのことを実装した方法を思い出しました。 ここですべてが同じになるのではないかと心配しました。 しかし、Elixirは私たちを自分自身から守ります。これは、テスト時にバランスを見つけるのに役立ちます。 構文は明確でクリーンです。 必要なコードの量が大幅に減少しました。 さらに非常に便利なライブラリを提供してくれた、Thoughtbotの輝かしいスタッフに感謝します。



Wunschからの結論



今日は非常に短い結論です。 エリクサーコミュニティに登録して、毎週ロシア語で興味深い記事を受け取ってください。



シリーズの他の記事



  1. エントリー
  2. ログイン
  3. 役割を追加
  4. コントローラーで役割を処理します
  5. ExMachinaを接続します
  6. マークダウンのサポート
  7. コメントを追加
  8. コメントで終了
  9. チャンネル
  10. チャネルテスト
  11. おわりに




研究の成功、私たちと一緒に!



All Articles