I have just installed the edge version of rspec and rspec-rails and some
of my specs related to views now fail.
I use the helper current_user in my views, to access the user that is
actually logged in.
I was simply using the sentence
assigns[:current_user] = stub_model(User,:role => “whatever”)
and now, my spec fails in current_user.role because not it says that the
current_user is nil.
You have a nil object when you didn’t expect it!
The error occurred while evaluating nil.role
I have try with something like this.
describe “/clientes/new.html.haml” do
include ClientesHelper
before do
user = stub_model(User,:role => “Comercial”)
controller.stub!(:current_user).and_return(user)
cliente = stub_model(Cliente, :new_record? => true)
assigns[:cliente] = cliente
end
it “should show th New form” do
render “/clientes/new.html.haml”
response.should have_tag(“form[action=?][method=post]”,
clientes_path) do
with_tag(“input#cliente_codigo[name=?]”, “cliente[codigo]”)
with_tag(“input#cliente_nombre[name=?]”, “cliente[nombre]”)
with_tag(“input#cliente_domicilio[name=?]”, “cliente[domicilio]”)
with_tag(“input#cliente_poblacion[name=?]”, “cliente[poblacion]”)
with_tag(“input#cliente_provincia[name=?]”, “cliente[provincia]”)
with_tag(“input#cliente_telefono[name=?]”, “cliente[telefono]”)
end
end
end
and throw this error:
undefined local variable or method `controller’ for
#Spec::Rails::Example::ViewExampleGroup::Subclass_1:0xb70704ec
Why?
How can I mock the current_user helper for using in my views?
Thanks
Juanma C.
Well, it seems pretty obvious that I can’t use “controller” to mock
controller methods in the view specs, but I was assigning a mock for the
current logged-in user to the @current_user variable and it worked on
rspec 1.1.4
I was doing this:
assigns[:current_user] = stub_model(User, :role => “whatever”)
and I could check the role of the user in the view with
current_user.role.
Was it correct or I had to do it in another way?
Thanks
Juanma C.
I can’t tell from your post whether you meant to type an instance or
local
variable when noting that you “could check the role of the user in the
view
with current_user.role,” since you mentioned an instance variable
earlier.
assigns[:current_user] = … sets up an instance variable,
@current_user,
for use in your view. You should be using @current_user instead of
current_user.
Regards,
Craig
Thanks Craig, but I think I don’t understand completely.
“current_user” is a helper method provided by the plugin
restful_authentication
to access the @current_user variable as I understand.
It is defined in lib/authenticated_system.rb.
We use this helper to access the current logged-in user in the system
from any view.
Do you think that I have to use the variable directly?
Juanma
On Mon, Sep 29, 2008 at 6:35 AM, Juanma C. [email protected]
wrote:
Thanks Craig, but I think I don’t understand completely.
“current_user” is a helper method provided by the plugin
restful_authentication
to access the @current_user variable as I understand.
It is defined in lib/authenticated_system.rb.
We use this helper to access the current logged-in user in the system
from any view.
Do you think that I have to use the variable directly?
This is precisely why it’s better to stub methods than try to set up
internal state (instance variables).
The assigns hash represents instance variables set IN THE VIEW by the
controller action. While it is true that the current_user method from
restful auth uses @current_user, it does so IN THE CONTROLLER, not in
the view. So when the view calls current_user, that call is forwarded
to the controller, which is where the @current_user instance variable
lives.
What you can do that will work in this case is to stub the
current_user method directly on the view:
template.stub!(:current_user).and_return(user)
Now the call won’t get delegated to the controller, and you don’t have
to set up real state in the controller to get a simulated result in
the view. Much less brittle for your isolated examples.
As always, isolated examples don’t tell you when the app works as
expected. They tell you when the individual components work as
expected. You still need higher level coverage from a tool like
cucumber or rails integration tests.
Cheers,
David