Stub model in a view - ruby-on-rails

I wan't to write spec for a view in Rails with Rspec. I wrote this:
require 'spec_helper'
describe "homepage/index.html.erb" do
it 'has list of publications with id #publications' do
render
expect(rendered).to have_selector('ul#publications')
end
it 'has publications on the list' do
assign(:publications, [
stub_model(Publication, content: 'First publication.'),
stub_model(Publication, content: 'Second publication.')
])
render
rendered.should have_content('First publication.')
rendered.should have_content('Second publication.')
end
end
But stub_model seems to be not working.
rspec
.....F.
Failures:
1) homepage/index.html.erb has list of publications with id #publications
Failure/Error: render
ActionView::Template::Error:
undefined method `each' for nil:NilClass
# ./app/views/homepage/index.html.erb:2:in `_app_views_homepage_index_html_erb___3273264012123365698_43368240'
# ./spec/views/homepage/index.html.erb_spec.rb:5:in `block (2 levels) in <top (required)>'
Finished in 0.17634 seconds
7 examples, 1 failure
How can I stub this properly?

The description given in your failure message indicates that your failing on the example above the example with the stubs. In that example, nothing has been assigned to the instance variable #publications, so the view is presumably raising the error you're seeing as a result of executing #publications.each ....
But as #phoet implied, you really should provide the code that is failing.

I don't think that it is a good idea to stub models in such (integration or acceptance) tests.
But if you would like to do it you should stub query to DB (when you are trying to stub assigns). For example you have Publication.all in your action - so you can stub
Publication.stub(all:
[
stub_model(Publication, content: 'First publication.'),
stub_model(Publication, content: 'Second publication.')
])

Related

Wrong translation path in rspec view tests

Hey guys I am running into a bit of trouble with a simple view test written using Rspec. The case is pretty simple. I want to render a page that should display a message asking the customer if he/she is new.
The page contains several subsections that contain translations. The problem is that Rspec puts a "test" in this translation path, so the correct translation is not found.
Rspec test:
require "rails_helper"
RSpec.describe 'checkout/start/index' do
context "with no logged in customer" do
it "should render the #index page and display the registration and login form" do
render
expect(rendered).to match(/Sie sind neu bei uns?/)
end
end
end
Response:
Randomized with seed 40265
checkout/start/index
with no logged in customer
calls #index and displays the registration and login form (FAILED - 1)
Failures:
1) checkout/start/index with no logged in customer calls #index and displays the registration and login form
Failure/Error: <%= t(".checkout_#{controller_name}_sub_headline") %>
ActionView::Template::Error:
translation missing: de.checkout.shared.sub_headline.checkout_test_sub_headline
# /home/arthur/.rvm/gems/ruby-3.1.2/gems/i18n-1.12.0/lib/i18n.rb:394:in `handle_exception'
# /home/arthur/.rvm/gems/ruby-3.1.2/gems/i18n-1.12.0/lib/i18n.rb:367:in `translate_key'
# /home/arthur/.rvm/gems/ruby-3.1.2/gems/i18n-1.12.0/lib/i18n.rb:222:in `translate'
# ./app/views/checkout/shared/_sub_headline.html.erb:6:in `_app_views_checkout_shared__sub_headline_html_erb__648894094841044844_23060'
# ./app/views/checkout/start/index.html.erb:8:in `_app_views_checkout_start_index_html_erb__2185710400981636407_23000'
# ./spec/views/checkout/start_spec.rb:10:in `block (3 levels) in <top (required)>'
# ------------------
# --- Caused by: ---
# I18n::MissingTranslationData:
# translation missing: de.checkout.shared.sub_headline.checkout_test_sub_headline
# /home/arthur/.rvm/gems/ruby-3.1.2/gems/i18n-1.12.0/lib/i18n.rb:394:in `handle_exception'
Top 1 slowest examples (0.03185 seconds, 6.4% of total time):
checkout/start/index with no logged in customer calls #index and displays the registration and login form
0.03185 seconds ./spec/views/checkout/start_spec.rb:9
Finished in 0.49579 seconds (files took 1.69 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/views/checkout/start_spec.rb:9 # checkout/start/index with no logged in customer calls #index and displays the registration and login form
Randomized with seed 40265
Is there any way to override this path for the test, or any other way to tell Rspec where to look for the correct translation?
Many thanks in advance
You have created a translation that's dependent upon the controller_name, which as you're seeing is different in your test environment because of the way Rails view tests work. If you need that in your code, then in your test I would stub it out so you're providing what your code expects. I'm not sure, but that's probably something like allow(helper).to receive(:controller_name) { 'your_controller_name' }

rspec testing strong params and building a model

I am attempting to write a model test, like so:
require 'spec_helper'
describe Five9List do
before :each do
#five9_list = Five9List.new(name: 'test_list', size: '100')
end
describe "#new" do
it "takes two parameters and returns a Five9List object" do
#five9_list.should be_an_instance_of Five9List
end
end
describe "#name" do
it "returns the correct name" do
#five9_list.name.should eql "test_list"
end
end
describe "#size" do
it "returns the correct size" do
#five9_list.size.should eql 100
end
end
end
Currently, this succeeds and works fine. That's because my model is using attr_accessible, like so:
class Five9List < ActiveRecord::Base
attr_accessible :name, :size
end
If I want to get rid of attr_accessible and follow the rails 4 convention of using strong_params, how would I write that to where my rspec test would still succeed?
Adding this in my controller:
private
def five9_list_params
params.require(:five9_list).permit(:name, :size)
end
And removing attr_accessible does not work.
EDIT
Here is the error I receive from rspec .:
Failures:
1) Five9List#name returns the correct name
Failure/Error: #five9_list.name.should eql "test_list"
expected: "test_list"
got: nil
(compared using eql?)
# ./spec/models/five9_list_spec.rb:16:in `block (3 levels) in <top (required)>'
2) Five9List#size returns the correct size
Failure/Error: #five9_list.size.should eql 100
expected: 100
got: nil
(compared using eql?)
# ./spec/models/five9_list_spec.rb:22:in `block (3 levels) in <top (required)>'
Finished in 0.03303 seconds
4 examples, 2 failures, 1 pending
Failed examples:
rspec ./spec/models/five9_list_spec.rb:15 # Five9List#name returns the correct name
rspec ./spec/models/five9_list_spec.rb:21 # Five9List#size returns the correct size
Randomized with seed 20608
There's nothing wrong with your spec. I can only guess that you're not running Rails 4 or you've installed the ProtectedAttributes gem.

Rails Engine with RSpec and FactoryGirl

I followed a few tutorials and docs of FactoryGirl to use with RSpec. Currently I get one error when trying to use FactoryGirl.create:
describe "GenericRecipesController" do
describe "GET 'index'" do
it "displays list of generic recipes" do
generic_recipe = FactoryGirl.create(:generic_recipe)
visit '/recipe'
response.should be_success
end
end
end
And the error:
GenericRecipesController GET 'index' displays list of generic recipes
Failure/Error: generic_recipe = FactoryGirl.create(:generic_recipe)
NameError:
uninitialized constant GenericRecipe
# ./spec/integration/generic_recipes_spec.rb:8:in `block (3 levels) in <top (required)>'
The rest of code is there.
You can try this:
factory :generic_recipe, class: EdibleRecipe::GenericRecipe do
# ...
end
I think problem in a nesting model in module
Upd: delete file /spec/factories.rb, in file /spec/support/factories.rb make
factory :generic_recipe, class: EdibleRecipe::GenericRecipe do
When you will run tests, probably will see 'can not load table'. Make
rake db:migrate RAILS_ENV=test
and try again.
You don't seem to have a GenericRecipe model in your app. Factory Girl is looking for a Model called GenericReciper and can't find it.

RSpec fails for no obvious reason

So I'm using rspec to test my code as I'm going through the Rails Tutorial, and I keep getting this error when I test the code in listing 3.20. Everything checks out when I look at it with my eyeball, but RSpec doesn't seem to like it.
(Note that I just did one of the pages, not all three because they all give the same error)
james#tristan:~/rails_projects/sample_app$
rspec
spec/controllers/pages_controller_spec.rb
F...
Failures:
1) PagesController should have the
right title
Failure/Error: response.should have_selector("title",
expected following output to contain a | Home tag:
# ./spec/controllers/pages_controller_spec.rb:13:in
`block (2 levels) in '
Finished in 0.97999 seconds 4
examples, 1 failure
james#tristan:~/rails_projects/sample_app$
At the top of that spec file it says:
before(:each) do
#
# Define #base_title here.
#
end
Does your spec assign a value to #base_title?

Understanding RSpec Failure

I'm getting these failures when running rspec spec/. The spec that is failing is was auto-generated with the scaffolding. I'm trying to understand RSpec but I don't know where to begin looking for the cause other than it feels like some method is missing?!? Yet, app appears to be working fine. Nothing about these failures appears in test.log. Is there another place I should be looking for hints to track this down?
$ rspec spec/
.....................F.F.
Failures:
1) clowns/edit.html.haml renders the edit clown form
Failure/Error: render
undefined method `to_sym' for nil:NilClass
# ./app/views/clowns/_form.html.haml:4:in `block in _app_views_clowns__form_html_haml__3590088286240866241_2176114460_3896491916910336970'
# ./app/views/clowns/_form.html.haml:1:in `_app_views_clowns__form_html_haml__3590088286240866241_2176114460_3896491916910336970'
# ./app/views/clowns/edit.html.haml:3:in `_app_views_clowns_edit_html_haml___574620942879655923_2176081980_599706797287605391'
# ./spec/views/clowns/edit.html.haml_spec.rb:13:in `block (2 levels) in <top (required)>'
2) clowns/new.html.haml renders new clown form
Failure/Error: render
undefined method `to_sym' for nil:NilClass
# ./app/views/clowns/_form.html.haml:4:in `block in _app_views_clowns__form_html_haml__3590088286240866241_2176114460_3896491916910336970'
# ./app/views/clowns/_form.html.haml:1:in `_app_views_clowns__form_html_haml__3590088286240866241_2176114460_3896491916910336970'
# ./app/views/clowns/new.html.haml:3:in `_app_views_clowns_new_html_haml__1085372210838170129_2159651900_599706797287605391'
# ./spec/views/clowns/new.html.haml_spec.rb:12:in `block (2 levels) in <top (required)>'
Finished in 1.03 seconds
27 examples, 2 failures, 2 pending
And here is the spec that apparently fails (edit.html.haml_spec.rb). It was auto-generated by rails g scaffold Clown name:string balloons:integer:
#spec/views/clowns/edit.html.haml_spec.rb
require 'spec_helper'
describe "clowns/edit.html.haml" do
before(:each) do
#clown = assign(:clown, stub_model(Clown,
:name => "MyString",
:balloons => 1
))
end
it "renders the edit clown form" do
render
# Run the generator again with the --webrat-matchers flag if you want to use webrat matchers
assert_select "form", :action => clown_path(#clown), :method => "post" do
assert_select "input#clown_name", :name => "clown[name]"
assert_select "input#clown_balloons", :name => "clown[balloons]"
end
end
end
Are you also using simple_form (or perhaps even formtastic)? I get the same error when I convert the scaffold forms from standards forms to simple_form forms (form_for(#user) => simple_form_for(#user)).
It still works, as you say, so I'm not sure it's worth worrying about. I think you'd be better off just letting Cucumber worry about it. Sarah Mei says view specs are a waste of time. :-)

Resources