2017-04-16 127 views
0

我有用于登录用户的端点。我编写了集成测试和控制器测试,但它们看起来非常相似,除了我在控制器测试中测试了更多的边缘案例(例如,用户尝试使用不正确的电子邮件登录)。测试的内容似乎并没有什么不同,所以如果有人能够阐明他们应该如何改变,那将是非常好的。Phoenix:API集成测试vs控制器测试

集成测试:

defmodule SigningInUserTest do 
    use ParrotApi.ConnCase 
    alias ParrotApi.Router 

    @opts Router.init([]) 
    describe "POST api/v1/sessions" do 
    test "success" do 
     email = "[email protected]" 
     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 = "[email protected]" 
     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 = "[email protected]" 
     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 = "[email protected]" 
     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: "[email protected]", 
      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 

回答

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