i'm trying to run a controller test:
the controller code is
def aix_service_accounts
#no_dn_users= Hash.new
record = 0
#no_dn_users[record]= Hash.new
#no_dn_users[record]['aix_username'] ="abc"
end
The rspec code is
it "should show aix_service_accounts" do
get :aix_service_accounts
expect(assigns(:no_dn_users[0]['aix_username'])).to eq 'abc'
end
The result is
Failures:
1) AixController should show aix_service_accounts
Failure/Error: expect(assigns(:no_dn_users[0]['aix_username'])).to eq 'abc'
expected: "abc"
got: {"marked_for_same_origin_verification"=>true, "no_dn_users"=>{0=>{"aix_username"=>"abc"}}}
(compared using ==)
Diff:
## -1,2 +1,3 ##
-"abc"
+"marked_for_same_origin_verification" => true,
+"no_dn_users" => {0=>{"aix_username"=>"abc"}},
# ./spec/controllers/aix_controller_spec.rb:29:in `block (2 levels) in <top (required)>'
Could anyone help and explain the reason to me? Thanks!
Sure - you're trying to ask for a single key called :no_dn_users[0]['aix_username'] from the assigns. You need to change that to:
assigns(:no_dn_users)[0]['aix_username']
instead.
Ie, get out the first part by the key :no_dn_users, this will be the hash-inside-an-array that you're then referencing using indexing
Related
Hello i have problem with testing JSONAPI with rspec and airborne.
GET model below
https://i.stack.imgur.com/Cyf75.png
Im testing it this way https://i.stack.imgur.com/Y9rHt.png
Rspec output:
Failures:
1) GET on /contacts should validate types
Failure/Error: expect_json('books.0', title: 'The Great Escape')
Airborne::PathError:
Expected NilClass
to be an object with property 0
# /home/robert/.rvm/gems/ruby-2.4.0/gems/airborne-0.2.5/lib/airborne/path_matcher.rb:21:in `rescue in block in get_by_path'
# /home/robert/.rvm/gems/ruby-2.4.0/gems/airborne-0.2.5/lib/airborne/path_matcher.rb:18:in `block in get_by_path'
# /home/robert/.rvm/gems/ruby-2.4.0/gems/airborne-0.2.5/lib/airborne/path_matcher.rb:9:in `each'
# /home/robert/.rvm/gems/ruby-2.4.0/gems/airborne-0.2.5/lib/airborne/path_matcher.rb:9:in `each_with_index'
# /home/robert/.rvm/gems/ruby-2.4.0/gems/airborne-0.2.5/lib/airborne/path_matcher.rb:9:in `get_by_path'
# /home/robert/.rvm/gems/ruby-2.4.0/gems/airborne-0.2.5/lib/airborne/request_expectations.rb:137:in `call_with_path'
# /home/robert/.rvm/gems/ruby-2.4.0/gems/airborne-0.2.5/lib/airborne/request_expectations.rb:18:in `expect_json'
# ./book_resource.rb:10:in `block (2 levels) in <top (required)>'
# ------------------
# --- Caused by: ---
# NoMethodError:
# undefined method `[]' for nil:NilClass
# /home/robert/.rvm/gems/ruby-2.4.0/gems/airborne-0.2.5/lib/airborne/path_matcher.rb:57:in `process_json'
Finished in 0.03121 seconds (files took 0.17681 seconds to load)
1 example, 1 failure
Your API response doesn't have the key books. Instead, it is returning the response as { "data": [ ... ] }.
So, in your tests, you need to specify expect_json('data.0', ...), instead of expect_json('books.0', ...).
Hope that should resolve this issue.
Already solve with:
describe Api::UsersController do
describe 'GET on /users' do
before do
FactoryGirl.create('user', name: 'Jack McClure')
FactoryGirl.create('user', name: 'Johny Reaper')
FactoryGirl.create('user', name: 'Niko Bellic')
end
it 'should return valid user' do
get :index, format: 'json'
expect_json('data.0.attributes', name: "Jack McClure")
expect_json('data.2.attributes', name: 'Niko Bellic')
end
end
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.
I am setting up a test that should expect calls on two "subscriber" instances:
it "sends out sms to all the subscribers" do
#user.subscribers.create!
#user.subscribers.create!
Subscriber.any_instance.should_receive(:send_message).with(#message).times(2)
post :create, {:broadcast => valid_attributes}
end
The actual code is:
def create
#broadcast = Broadcast.new(params[:broadcast])
current_user.subscribers.each do |subscriber|
subscriber.send_message(#broadcast.message)
end
...
The error:
Failure/Error: post :create, {:broadcast => valid_attributes}
ArgumentError:
wrong number of arguments (1 for 0)
# ./app/controllers/broadcasts_controller.rb:41:in `block in create'
# ./app/controllers/broadcasts_controller.rb:40:in `create'
# ./spec/controllers/broadcasts_controller_spec.rb:73:in `block (4 levels) in <top (required)>'
For some reason, if I add the line: Subscriber.any_instance.should_receive(:send_message).with(#message).times(2), it fails with that error message. If I remove that line, the test runs smoothly (no wrong number of argument problem). What am I doing wrong?
The error you're getting is because the 'times' method is expected to be chained onto one of the other "receive count" expectations. You can use any one of the following:
should_receive(:send_message).with(#message).exactly(2).times
should_receive(:send_message).with(#message).at_most(2).times
You can also use one of the other alternatives that does not require the 'times' method:
should_receive(:send_message).with(#message).twice
should_receive(:send_message).with(#message).at_most(:twice)
More on that can be found in the rspec-mocks documentation
You may need to set the expectation BEFORE creating the subscribers:
it "sends out sms to all the subscribers" do
Subscriber.any_instance.should_receive(:send_message).with(#message).twice
#user.subscribers.create!
#user.subscribers.create!
post :create, {:broadcast => valid_attributes}
end
I'm testing my REST API and the issue i have is that i create a video, using factory girl and i only get a result from the API the second time i run the test. Even if i comment out the video creation after the first run, so there is no second video created.
This only works when i configure
config.use_transactional_fixtures = false
so test data will stay in the database.
My Spec file
describe "API Version 1" do
describe "Videos" do
let(:video) { FactoryGirl.create(:video) }
before { get api_v1_videos_path }
it "should work" do
response.status.should be(200)
end
it "should return the video" do
output = JSON.parse(response.body)
output.should == video.title
end
end
end
Error after first run
1) API Version 1 Videos should return the video
Failure/Error: output.should == video.title
expected: "Darknight"
got: [] (using ==)
# ./spec/requests/api/v1_spec.rb:15:in `block (3 levels) in <top (required)>'
Error after 2nd run (still error but returns results)
1) API Version 1 Videos should return the video
Failure/Error: output.should == video.title
expected: "Darknight"
got: [{"id"=>3, "title"=>"Darknight", "video"=>"thevideo.mp4", "stream"=>"playlist.m3u8", "poster"=>"/uploads/test/video/3_darknight/poster/testimage.jpg", "categories"=>[{"id"=>3, "title"=>"test category"}]}] (using ==)
Diff:
## -1,2 +1,7 ##
-"Darknight"
+[{"id"=>3,
+ "title"=>"Darknight",
+ "video"=>"thevideo.mp4",
+ "stream"=>"playlist.m3u8",
+ "poster"=>"/uploads/test/video/3_darknight/poster/testimage.jpg",
+ "categories"=>[{"id"=>3, "title"=>"test category"}]}]
# ./spec/requests/api/v1_spec.rb:15:in `block (3 levels) in <top (required)>'
Seems like rspec is not visiting the API after the video is created?
Change the below line...
let(:video) { FactoryGirl.create(:video) }
to
let!(:video) { FactoryGirl.create(:video) }
i'm new to rspec and ruby...
i have the following code in one of course_rspec.rb
...
it "check for active courses after enabling a course" do
course = Course.create(:title => "Testing", :description => "Testing")
course.enabled = true
course.save
active_courses = Course.where(:enabled => true)
active_courses.length.should eql 1
end
...
i get the following error
1) Course check for active courses after enabling a course
Failure/Error: active_courses.length.should eql 1
expected: 1
got: 0
(compared using eql?)
# ./course_spec.rb:86:in `block (2 levels) in <top (required)>'
why is the Course.where method return no objects? when i do this in rails console it works fine.
thanks for your help.
Are you running rails console in the test mode or in the development mode? Keep in mind that rails for testing and developing an application uses different databases.
Make sure that before the test all records are prepared and stored in the database. For this purpose you could use fixtures or factories (factory_girl for example).
ps.
Instead active_courses.length.should eql 1 you can use active_courses.should have(1).item which is more readable.