Unable to use subject/let syntax with Phoenix Framework's ConnTest
mspanc opened this issue · 0 comments
mspanc commented
I am using pavlov to test Phoenix Framework controllers.
Consider the following example:
defmodule MyApp.UserTest do
use MyApp.ConnCase, async: true # default ConnCase generated by Phoenix
use Pavlov.Case, async: true
import Pavlov.Syntax.Expect
let(:base_url) do
"/api/user"
end
describe "POST (base_url)" do
context "if no Authorization header was passed" do
@endpoint MyApp.Endpoint
subject do
conn() |> post base_url
end
it "returns status code of 401 Unauthorized" do
expect subject.status |> to_eq 401
end
end
end
end
It will end up with
** (CompileError) test/controllers/user_test.exs:52: function conn/0 undefined
(stdlib) lists.erl:1337: :lists.foreach/2
test/controllers/user_test.exs:48: (module)
test/controllers/user_test.exs:47: (module)
If I add module names:
defmodule MyApp.UserTest do
use MyApp.ConnCase, async: true # default ConnCase generated by Phoenix
use Pavlov.Case, async: true
import Pavlov.Syntax.Expect
let(:base_url) do
"/api/user"
end
describe "POST (base_url)" do
context "if no Authorization header was passed" do
@endpoint MyApp.Endpoint
subject do
Phoenix.ConnTest.conn() |> Phoenix.ConnTest.post base_url # Here we add module names
end
it "returns status code of 401 Unauthorized" do
expect subject.status |> to_eq 401
end
end
end
end
it will end up with the following error:
** (CompileError) nofile:52: you must require Phoenix.ConnTest before invoking the macro Phoenix.ConnTest.post/2
(elixir) expanding macro: Kernel.|>/2
nofile:52: :"Elixir.MyApp.UserControllerTest.POST (base_url).if no Authorization header was passed".subject/0
(elixir) lib/module.ex:360: Module.eval_quoted/4
(elixir) lib/enum.ex:543: anonymous fn/3 in Enum.each/2
(elixir) lib/enum.ex:1275: anonymous fn/3 in Enum.reduce/3
(elixir) lib/stream.ex:717: Stream.do_transform_each/3
The same happens if I try to use let
.
That makes let/subject
syntax useless for testing Phoenix controllers.
let/subject
IMO should be always evaluated in the scope of the calling function.