hi guys,
I’m trying to pick up Rspec to port an existing application in rails
2.3.8 to rails 3.
I’m using the pragmatic “The Rspec book” (dec 2010) as a reference.
read around the book and the rspec docs.
assign method
syntax: assign( , <block usually calling double()
or mock_model)>
what it means to me: run the codes in the block and assign the
value evaluated to the symbol name.
let method
syntax: let(method_name>) { }
will not run until it is called
-used with before(), end() to set up usually instance variables
-the contents in its block will be evaluated when called
-here’s what http://rdoc.info/gems/rspec/1.3.2/frames says when i
looked up the source for let.
------ Documentation extract for “let” (start) ----------------------
def let(name, &block)
define_method name do @assignments ||= {} @assignments[name] ||= instance_eval(&block)
end
end
------ Documentation extract for “let” (end) ----------------------
-to call the contents of the block, we will refer to it by the method
name (which is a symbol)
There’s this example below (from the rspec book page 338) which I am
a little confused with.
1 require ‘spec_helper’
2
3 describe “messages/new.html.erb” do
4 let(:message) do
5 mock_model(“Message”).as_new_record.as_null_object
6 end
7
8 before do
9 assign(:message, message)
10 end
11
12 it “renders a form to create a message” do
13 render
14 rendered.should have_selector(“form”,
15 :method => “post”,
16 :action => messages_path
17 ) do |form|
18 form.should have_selector(“input”, :type => “submit”)
19 end
20 end
21
22 it “renders a text field for the message title” do
23 message.stub(:title => “the title”)
24 render
25 rendered.should have_selector(“form”) do |form|
26 form.should have_selector(“input”,
27 :type => “text”,
28 :name => “message[title]”,
29 :value => “the title”
30 )
31 end
32 end
33 end
------------ Extract end ----------------------------
My question is, line 9 seems to imply that the content of :message
(the mocked Message object) is being
assigned to the ‘message’ object but as per what I have read in the
Rspec book, the first argument in the call to assign() is actually the
variable that is getting assigned with.
Yet, the extract above still works when i run “rake spec”.
also, i have just read a little more in the rspec book.
here’s an extract:
------------- extract start ---------------------
assign()
View specs expose an assign method, which we use to provide data to
the view. Modify the spec as follows:
describe “messages/show.html.erb” do
it “displays the text attribute of the message” do
assign(:message, double(“Message”, :text => “Hello world!”))
render
rendered.should contain(“Hello world!”)
end
end
The new first line of the example creates a test double, which stubs
the text( ) method with a return value of Hello world! and assigns
it to an @message instance variable on the view.
------------- extract end ---------------------
If :message (in the view spec) can correspond to @message variable (in
the actual show.html.erb view), is this a Rspec convention/thing?
Sorry, Im just trying to find more resources to read up on rspec but
i’m having not much luck. Appreciate your thoughts.
Hello David
Thanks for that. Doesn’t assign have 2 arguments with the first being
the
variable to be assigned to and the second being the contents?
On Aug 3, 2011 7:01 PM, “ct9a” [email protected] wrote:
it “displays the text attribute of the message” do
it “displays the text attribute of the message” do
------------- extract end ---------------------
If :message (in the view spec) can correspond to @message variable (in
the actual show.html.erb view), is this a Rspec convention/thing?
Sorry, Im just trying to find more resources to read up on rspec but
i’m having not much luck. Appreciate your thoughts.
Thank you .
Keep in mind that rspec-rails is a thin wrapper around the built-in
Rails testing framework. The convention of relating a symbol in the spec
to an instance variable in the view was established by Rails with the assigns method in functional tests (controller specs in rspec):
thing = Factory(:thing)
get :index
assigns(:thing).should eq(thing)
In the last line, assigns(:thing) refers to the @thing instance
variable in the view.
Hello David
Thanks for that. Doesn’t assign have 2 arguments with the first being the
variable to be assigned to and the second being the contents?
Yes, assign, in view specs, has two arguments. assigns (plural), in
controller specs (and provided by Rails) takes only one. assign is a
setter for a single instance variable, assigns is a getter which keys
into a map of all assigned instance variables.
HTH,
David
PS - I had to move your post to the bottom and quote my own comments
from the previous email to which you were responding. Please read Top Posting and Bottom Posting and make it easier for people to be
helpful to you in a way that is understandable to everyone else.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.