2016-11-23 39 views
1

從下面的代碼,當我打電話conn.params["geo"],我得到以下錯誤:Plug.Conn.Unfetched沒有實現訪問行爲

test/plugs/geoip_test.exs:4 
** (UndefinedFunctionError) function Plug.Conn.Unfetched.fetch/2 is undefined (Plug.Conn.Unfetched does not implement the Access behaviour) 
stacktrace: 
    (plug) Plug.Conn.Unfetched.fetch(%{:__struct__ => Plug.Conn.Unfetched, :aspect => :params, "geo" => "Mountain View, US", "ip" => "8.8.8.8"}, "geo") 

...

defmodule AgilePulse.Plugs.GeoIPTest do 
    use AgilePulse.ConnCase 

    test "returns Mountain View for 8.8.8.8" do 
    conn = build_conn 
    params = Map.put(conn.params, "ip", "8.8.8.8") 
    conn = Map.put(conn, :params, params) |> AgilePulse.Plugs.GeoIP.call(%{}) 

    assert conn.params["geo"] == "Mountain View, US" 
    end 

end 

defmodule AgilePulse.Plugs.GeoIP do 
    import Plug.Conn 

    def init(opts), do: opts 

    def call(%Plug.Conn{params: %{"ip" => ip}} = conn, _opts) do 
    geo = set_geo(ip) 
    params = Map.put(conn.params, "geo", geo) 
    Map.put(conn, :params, params) 
    end 

    def call(conn, _opts), do: conn 

    ... 

end 

可能有人開導我爲什麼這是失敗的,什麼是合適的解決方案? TY!

回答

3

簡短的回答:更改此:

params = Map.put(conn.params, "ip", "8.8.8.8") 

要:

params = %{"ip": "8.8.8.8"} 

說明:Phoenix.ConnTest.build_conn/0返回Connparams設置爲%Plug.Conn.Unfetched{}。通過使用上Map.put,你不復位的__struct__的價值,而只是添加一個新的關鍵:當你打電話params["geo"]

%Plug.Conn{ ..., 
params: %{:__struct__ => Plug.Conn.Unfetched, :aspect => :params, 
    "ip" => "8.8.8.8"}, ... } 

,花好月圓看到那params是一個結構,並試圖調用fetch/2函數在結構的模塊上,它不存在。若要將params重置爲普通地圖(以便Elixir在使用方括號語法時調用Map.get),則可以僅執行params = %{"ip": "8.8.8.8"}

+0

不錯!所以在我的具體情況下,爲了讓測試通過,必須使用params =%{「ip」=>「8.8.8.8」}。但感謝你! – keruilin