2016-11-23 4 views
1

Aus dem folgenden Code, wenn ich conn.params["geo"] nennen, bekomme ich folgende Fehlermeldung:Plug.Conn.Unfetched implementiert nicht das Zugriffsverhalten

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 

Könnte jemand aufklären Ich darüber, warum das scheitert und was die angemessene Lösung ist? TY!

Antwort

3

Kurze Antwort: diese Änderung:

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

An:

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

Erläuterung: Phoenix.ConnTest.build_conn/0 eine Conn mit params Satz %Plug.Conn.Unfetched{} zurückgibt. Durch die Verwendung von Map.put auf, dass Sie nicht zurücksetzen den Wert von __struct__, sondern nur einen neuen Schlüssel hinzu:

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

Wenn Sie params["geo"] später anrufen, sieht Elixir dass params ist eine Struktur, und versucht, die fetch/2 anrufen Funktion auf dem Modul der Struktur, die nicht existiert. Um params auf eine normale Karte zurückzusetzen (so dass Elixir Map.get aufruft, wenn Sie die eckige Klammern-Syntax verwenden), können Sie einfach params = %{"ip": "8.8.8.8"} tun.

+0

nett! Also musste in meinem speziellen Fall params =% {"ip" => "8.8.8.8"} verwendet werden, um den Test zu bestehen. aber dank dir hat es geklappt! – keruilin

Verwandte Themen