Phoenix:API集成测试与控制器测试

时间:2017-04-16 04:02:30

标签: elixir integration-testing phoenix-framework

我有一个用于登录用户的端点。我编写了集成测试和控制器测试,但它们看起来非常相似,除了我在控制器测试中测试了更多边缘情况(例如用户尝试使用不正确的电子邮件登录)。测试的内容似乎并没有什么不同,所以如果有人能够阐明它们应该如何区别,那将会很棒。

集成测试:

defmodule SigningInUserTest do
  use ParrotApi.ConnCase
  alias ParrotApi.Router

  @opts Router.init([])
  describe "POST api/v1/sessions" do
    test "success" do
      email = "eric@spaghetti.com"
      password = "ilovemodals"
      user = insert(:user,
                    email: email,
                    password_hash: Comeonin.Bcrypt.hashpwsalt(password))
      user_params = %{
        user: %{
          email: user.email,
          password: password,
        }
      }

      conn = build_conn(:post, "/api/v1/sessions", user_params)
      response = Router.call(conn, @opts)
      assert response.status == 201
    end

    test "failure" do
      email = "eric@spaghetti.com"
      password = "ilovemodalszzz"
      user = insert(:user,
                    email: email,
                    password_hash: Comeonin.Bcrypt.hashpwsalt(password))
      user_params = %{
        user: %{
          email: user.email,
          password: "bad_password",
        }
      }

      conn = build_conn(:post, "/api/v1/sessions", user_params)
      response = Router.call(conn, @opts)
      assert response.status == 401
    end
  end

控制器测试:

defmodule ParrotApi.SessionControllerTest do
  use ParrotApi.ConnCase

  setup %{conn: conn} do
    {:ok, conn: put_req_header(conn, "accept", "application/json")}
  end

  describe "#create" do
    test "returns the user when the email and password match", %{conn: conn} do
      email = "eric@spaghetti.com"
      password = "ilovemodals"
      user = insert(:user,
                    email: email,
                    password_hash: Comeonin.Bcrypt.hashpwsalt(password))
      rsvp = insert(:rsvp, user: user)
      user_params = %{
        user: %{
          email: email,
          password: password,
        }
      }
      conn = conn
             |> post(session_path(conn, :create), user_params)
      assert json_response(conn, 201)["data"] == %{
        "id" => user.id,
        "email" => user.email,
        "name" => user.name,
        "interests" => user.interests,
        "location" => user.location,
        "image_url" => user.image_url,
        "is_admin" => user.is_admin,
        "rsvps" => [rsvp.meetup_id],
      }
    end


    test "returns an error when the email and password don't match", %{conn: conn} do
      email = "eric@spaghetti.com"
      password = "ilovemodals"
      insert(:user,
             email: email,
             password_hash: Comeonin.Bcrypt.hashpwsalt(password))
      user_params = %{
        user: %{
          email: email,
          password: "bad_password",
        }
      }
      conn = conn
             |> post(session_path(conn, :create), user_params)
      assert json_response(conn, 401) == %{
        "message" => "The email and password you entered did not match our records. Please try again."
      }
    end

    test "returns an error when the user doesn't exist", %{conn: conn} do
      user_params = %{
        user: %{
          email: "eric@spaghetti.com",
          password: "bad_password",
        }
      }
      conn = conn
             |> post(session_path(conn, :create), user_params)
      assert json_response(conn, 401) == %{
        "message" => "The email and password you entered did not match our records. Please try again."
      }
    end
  end
end

1 个答案:

答案 0 :(得分:2)

您的集成测试似乎没有测试控制器测试已经覆盖的任何内容。但是,我相信你已经知道了。

您的控制器测试未涵盖的是通过Web服务器的路径。我建议启用服务器进行集成测试,并使用像HttpPoison这样的http客户端来执行实际请求。

我还建议您将这些测试标记为集成测试。如果您发现它们正在减慢测试速度,则默认情况下禁用它们。我们使用hound进行ExAdmin集成测试,我们会进行真正的浏览器填充和点击。默认情况下禁用这些测试。要做到这一点:

# my_app/config/test.exs
use Mix.Config
config :my_app, TestMyApp.Endpoint,
  http: [port: 4001],
  server: true

# my_app/test/test_helpers.exs
ExUnit.configure(exclude: [pending: true, integration: true])
ExUnit.start()

然后用:

运行它们
# Run all tests
mix test --include integration
# or run only integration
mix test --only integration