29
votes

I'm trying to test controller that expects a file upload using the phoenix framework. I followed the guide at the phoenix guides (http://www.phoenixframework.org/docs/file-uploads) and it works in the browser, but i'm having trouble writing a test for it. Here's what i did:

test "POST photo" do 
  { :ok, raw_file } = File.read "1528_27.jpg"
  conn() |> post("/api/v1/originals", %{ :image => raw_file })
  # do some assertions
end

The problem is, in the controller, my file never ends up as a %Plug.Upload struct, but as binary. So when testing, my params in the controller look like:

params: %{"image" => <<255, 216, 255, 225, 18, 180, 69, 120, 105, 102, 0, 0, 73, 73, 42, 0, 8, 0, 0, 0, 10, 0, 15, 1, 2, 0, 26, 0, 0, 0, 134, 0, 0, 0, 16, 1, 2, 0, 10, 0, ...>>},

and my controller blows up when trying to access params["image"].path. This works when uploading from the browser though, because then, i have the expected Upload struct in my params:

params: %{
  "image" => %Plug.Upload{
    content_type: "image/jpeg",
    filename: "1528_27.jpg",
    path: "/var/folders/98/40k7dt2d2sxf6xnkc_627lqc0000gp/T//plug-1448/multipart-280987-612081-2"
  }
},

How can i post a file from a test, so i get a %Plug.Upload struct, and not just binary?

1
I think one of these is the current location of the documentation @screnig linked to in the question: phoenixframework.readme.io/docs/file-uploads phoenixframework.org/blog/file-uploadsvaer-k
In case anybody want to have simple project to do upload file in Phoenix yodiw.com/simple-upload-file-local-phoenix-elixiryodi

1 Answers

52
votes

Put a file in your test directory somewhere (maybe test/fixtures) then use the Plug.Upload struct:

upload = %Plug.Upload{path: "test/fixtures/example.png", filename: "example.png"}
conn() |> post("/api/v1/originals", %{ :image => upload })