In my helper module, I have:
def abc(url)
...
if request.env['HTTP_USER_AGENT']
do something
end
end
In my spec file, I have:
describe "#abc" do
before(:each) do
#meth = :abc
helper.request.env['HTTP_USER_AGENT'] = "..."
end
it "should return the webstart jnlp file" do
#obj.send(#meth, "some_url").should ....
end
end
When I run the spec I have this error:
undefined local variable or method `request' for <ObjectWithDocHelperMixedIn:0x00000103b5a7d0>
How do I stub for request.env['...'] in my specs?
Thanks.
If you're using rspec-rails, you might be able to use controller.request in your helper tests.
Well, you've almost nothing to do:
before(:each) do
#meth = :abc
request.env['HTTP_USER_AGENT'] = "..."
end
I just gave this another try and this passes:
#in helper
def foo
request.env['HTTP_USER_AGENT']
end
#spec
it "foo" do
helper.request.env['HTTP_USER_AGENT'] = 'foo'
expect(helper.foo).to eq 'foo'
end
You can override user-agent set in the request env by doing the following.
before(:each) do
#meth = :abc
helper.request.user_agent = 'something else'
end
Then, in your spec:
it "does stuff" do
expect(helper.send(#meth, "some_url")).to # ...
end
for those who use request specs instead of controller specs and want to set request.env can do it like this:
Rails.application.env_config["whatever"] = "whatever"
this will make request.env["whatever"] available in your controllers with value you gave it in your specs.
Try this:
stub(request).env { {"HTTP_USER_AGENT" => "Some String"} }
Related
I need to write the RSpec test case for a module that has a private method and takes a single Argument.
module x
private
def fun(para)
end
end
I have a spec file where I tried to write a case like this. para and params are the arguments we can say.
RSpec.describe x do
class spec
include x
def initialize(params)
#params = params
end
end
describe "describe" do
context "context" do
it "should not truncate any normal text value" do
obj = spec.new(params)
# first
expect('dummy text').to obj.send(:fun).with(para)
# second
expect(obj).to receive(:fun).with(para);
#third
retr = obj.send(:fun).with(para);
expect retr.to eq('dummy text')
end
end
end
end
First, second and third, I used to get the output but these three ways didn’t work. They all are throwing some error.
Guys, can you help me to understant what I'm doing wrong? How can I resolve this?
If a method is private you should not have to test it directly but in some cases, why not. 🙂
I don't know what your fun method is supposed to do but here is some help.
RSpec.describe x do
class MySpec
include x
def initialize(params)
#params = params
end
end
describe "#fun" do
subject { my_spec.send(:fun).with(para) }
let(:my_spec) { MySpec.new(params) }
let(:params) { { foo: :bar } }
let(:para) { 'dummy text' }
it "should not truncate any normal text value" do
expect(subject).to eq(para)
end
end
end
I am just starting with RSpec and I am a bit lost. Can anyone please tell me how to write controller test for this method?
def list_c
#c = params.has_key?(:car) ? Car.new(car_listing_params) : Car.new()
#car.user = #user
#car.number_of_beds = 4 unless #car.number_of_beds
#car.car_type_tag = 'car' unless #car.car_type
#page_title = t('home.list_your_car')
end
A small example of controller test with rspec. You may get some idea from here.
# define your helper here.
require 'rails_helper'
# respect method to define test for your controller.
RSpec.describe YourController, type: :controller do
#define your factories for the set of your test
# you will decide which one you need to create from factory. Factory girl
# is used to mock factories.
# #c = params.has_key?(:car) ? Car.new(car_listing_params) : Car.new()
# #car.user = #user
# #car.number_of_beds = 4 unless #car.number_of_beds
# #car.car_type_tag = 'car' unless #car.car_type
# #page_title = t('home.list_your_car')
let(:user) { FactoryGirl.create :user }
before { sign_in user }
describe '#title' do
context 'with valid params' do
before do
# in before block, you can request a http call
# with parameter. This action repeats before each test runs.
get :your_action_of_current_controller, {a_param: a_value, a_date: "16-4-2015"}
end
it "renders successfully" do
# when you call a get request it assigns a response object.
expect(response).to be_success
end
it "returns json" do
expect(response.content_type).to be == 'application/json'
end
end
end
end
I have a problem with calling 'POST' method only once in my test suits.
let(:foo) {post :foo_controller arguments}
it 'FIRST: should validate post response first field' do
expect(foo[:first_field]).to match('something')
end
it 'SECOND: should validate post response second field' do
expect(foo[:second_field]).to match('something else')
end
Now foo's "POST" action is called twice.
I would like to make it that FIRST requests 'POST' and gets a request value, but SECOND only gets a value, which is persisted, without calling this 'POST'.
Is there an elegant way to solve this problem?
You could use a before(:all) block, not sure what post actually returns though.
before(:all) do
#my_response = post :foo_controller arguments
end
Hope that helps!
I us a small helper to fix this issue for me.
This is the helper module:
module ControllerSpecHelpers
# example:
#
# describe 'my request' do
# examine_response {get '/foo/bar'}
# it {should be_ok}
# end
#
#
def examine_response &block
before(:all) do
self.instance_exec &block
end
subject {last_response}
end
end
I configure Rspec to use it in my spec helper:
RSpec.configure do |conf|
# snip ...
conf.extend ControllerSpecHelpers
end
Then when I need to execute the call only once, and test multiple properties, I use it like this:
describe "when signing up" do
examine_response do
post "/signup", {email: 'signup#test.com', password: 'password'}
end
it {should be_ok}
it "body says welcome" do
expect(subject.body).to include 'welcome'
end
end
Here's more detail on how extending Rspec works:
http://timnew.github.io/blog/2012/08/05/extend-rspec-dsl/
I am trying to stub a helper method from my helper:
# sessions_helper.rb
require 'rest_client'
module SessionsHelper
BASE_URL = "http://localhost:1234"
def current_user?(token)
sessions_url = BASE_URL + "/sessions"
headers = {"X-AuthToken" => 12345}
begin
RestClient.get(sessions_url, headers)
return true
rescue RestClient::BadRequest
return false
end
end
end
I try to stub the current_user? to always return true in my unit test:
require 'spec_helper'
describe SessionsHelper do
it "Should not get current user with random token" do
SessionsHelper.stub(:current_user?).and_return(true)
expect(current_user?(12345)).to eq(false)
end
end
But the test still pass (I expect it returns true instead).
Is there something I miss to configure the stub method?
Thanks
You are not calling the method on SessionsHelper. You are calling it on self. So try stubbing the method on self.
describe SessionsHelper do
it "Should not get current user with random token" do
stub(:current_user?).and_return(true)
expect(current_user?(12345)).to eq(false)
end
end
any_instance should do what you want:
SessionsHelper.any_instance.stub(:current_user?).and_return(true)
As #Vimsha says, you got confused between the module and the instance, which is easy to do.
Using Rspec with Factory Girl. Trying to check out what data is being assigned in my controller (and test against it). Every post I've read says I should be able to get something out of assigns() but it keeps returning nill
Controller
def index
#stickies = Sticky.where(:user_id => current_user.id)
end
Spec
it "should assign stickies" do
foo = assigns(:stickies)
puts "foo = #{foo}"
end
Output
foo =
Am I using the wrong syntax? Is there a better way to do this? Thanks!!
You have to invoke the action first
describe StickiesController do
describe "GET index" do
it "should assign stickies" do
get :index
assigns(:stickies).should_not be_nil
end
end
end
If you are using the rspec > 2.99 you can use:
expect(assigns(:stickies)).not_to be_nil