What if I want to do something like
FactoryGirl.define do
factory :leaf do
end
factory :tree do
l = []
leaves do
l << Factory.build(:leaf)
//some app logic here
l
end
root l.first
end
end
How should I write this to make it work?
And maybe somebody have a link with really complex and untrivial examples of using FactoryGirl?
Thank you.
I'm not 100% sure I've followed what you're asking but would this work?
factory :tree do
after_build { |tree|
# build your leaves here
# ...
tree.root l.first
}
end
Related
I'm writing the following test:
let!(:city_areas) { FactoryGirl.create_list(:city_area, 30) }
before {
#city_areas = mock_model(CityArea)
CityArea.should_receive(:where).and_return(city_areas)
}
it 'should assign the proper value to city areas variable' do
get :get_edit_and_update_vars
assigns(:city_areas).should eq(city_areas.order("name ASC"))
end
to test the following method:
def get_edit_and_update_vars
#city_areas = CityArea.where("city_id = '#{#bar.city_id}'").order("name ASC").all
end
However, it fails out, saying that there's no method 'city_id' for nil:NilClass, leading me to believe it's still attempting to use the instance variable #bar.
How do I properly stub out this where statement to prevent this?
Why are you doing #city_areas = mock_model(CityArea) and then you never use #city_areas again?
I would test it this way:
inside the model CityArea create a named scope for this: where("city_id = '#{#bar.city_id}'").order("name ASC")
then in your controller spec you do
describe 'GET get_edit_and_update_vars' do
before(:each) do
#areas = mock('areas')
end
it 'gets the areas' do
CityArea.should_receive(:your_scope).once.and_return(#areas)
get :get_edit_and_update_vars
end
it 'assign the proper value to city areas variable' do
CityArea.stub!(:your_scope => #areas)
get :get_edit_and_update_vars
assigns(:city_areas).should eq(ordered)
end
end
and you should also create a spec for that new scope on the model spec
just a tip, you shouldn't use should_receive(...) inside the before block, use stub! inside before and use should_receive when you want to test that method is called
also, you shouldn't need to use factorygirl when testing controllers, you should always mock the models, the model can be tested on the model spec
I am creating a delayed job in my controller using the delay method as below:
JobProcessor.delay(:run_at => Time.now).process_job(options)
Now inside the process_job method I am doing
chunks = options[:collection].each_splice(10).to_a
chunks.each do |chunk|
self.delay(:run_at => Time.now).chunk_job
end
This is giving me error stack level too deep when I send request to the URL
What might be the issue? Please help.
I was able to make it work for me by doing some changes.
I changed the outer method process_job to be an instance method
And kept the rest of the code as it is.
So now my code looks like
JobProcessor.new.process_job(options)
in the controller, and inside the JobProcessor class I have
class JobProcessor
def process_job(options)
chunks = options[:collection].each_splice(10).to_a
chunks.each do |chunk|
self.class.delay(:run_at => Time.now).chunk_job(options)
end
end
handle_asynchronously :process_job, :run_at => Proc.new { 2.seconds.from_now }
def self.chunk_job(options)
# perform chunk job here
end
end
This works for me.
Say I have a class in Coffeescript:
class MyGame
constructor: () ->
#me = new Player
#opponents = [new Player, new Player]
which would like to test in Jasmine:
describe "MyGame", ->
beforeEach ->
window.game = new MyGame
it "should have two players", ->
expect(window.game.opponents.length).toEqual 2
But I get the error TypeError: Result of expression 'window.game.opponents' [undefined] is not an object.?
The window.game approach also seem awkward to me. If I try to define it as #game = new MyGame I get the error ReferenceError: Can't find variable: MyGame but I guess that has something to do with the way Coffeescript is wrapping things up?
UPDATE: The problem seems more like a reference problem as described above. I'm running with guard-jasmine which looks like
guard 'jasmine', :all_on_start => false, :all_after_pass => false do
watch(%r{app/assets/javascripts/(.+)\.(js\.coffee|js)}) { |m| "spec/javascripts/#{m[1]}_spec.#{m[2]}" }
watch(%r{spec/javascripts/(.+)_spec\.(js\.coffee|js)}) { |m| "spec/javascripts/#{m[1]}_spec.#{m[2]}" }
watch(%r{spec/javascripts/spec\.(js\.coffee|js)}) { "spec/javascripts" }
end
and my jasmine.yml file has:
src_files:
- "app/assets/**/*.js"
- "app/assets/**/*.coffee"
spec_files:
- '**/*[sS]pec.js.coffee'
asset_pipeline_paths:
- app/assets
- spec/javascripts
I get the an ReferenceError: Can't find variable: MyGame so I figure it's either something with the Rails 3.1 asset pipeline or the way Coffeescript wraps objects.
try defining your coffeescript class using the # operator as such:
class #MyGame
constructor: () ->
#me = new Player
#opponents = [new Player, new Player]
this will allow you to access the class from anywhere, such as from your jasmine tests, and also you can get away from attaching testing variables to window:
describe "MyGame", ->
beforeEach ->
#game = new MyGame
it "should have two players", ->
expect(#game.opponents.length).toEqual 2
the reason for this is that coffeescript goes out of its way to avoid introducing global variables by wrapping everything in a closure. unfortunately, this can be undesirable for object-oriented code. using the # operator attaches the class definition to the global this, which is window, and thus allows you to instantiate your classes as you like. you may have some global vars in your global space now, your classes, but for me its an ok trade-off. hope this helps!
I wasn't willing to accept modifying the namespace of my code by using an # symbol in front of all my backbone classes, so I dug around some more and the solution that worked for me was to require the application file in my spec/javascripts/spec.js.coffee file
#= require application
window.game = () -> new MyGame
This will assign a function that returns a new MyGame to window.game. Did you not just want the new instance directly?
window.game = new MyGame
The window.game approach also seem awkward to me.
How about this
describe "MyGame", ->
game = null
beforeEach ->
game = new MyGame
it "should have two players", ->
expect(game.opponents.length).toEqual 2
I have solved the problem by defining every class as class window.MyGame for example. In the spec files I put #= require my_file_name in the top.
Furthermore I have placed both jasminerice.js.coffee and jquery.js in app/assets/javascripts. This might not be the best solution as I assume they should be placed in spec/javascripts/helpers as my spec.js.coffee's content is #=require_tree ./.
I'm aware that this is not very elegant but it might help others in the same situation. #Thilo thanks for your inputs.
Previously in Factory girl, we could define sequences like so:
# /spec/factories.rb
FactoryGirl.define do
# this is the sequence in question:
sequence(:random_token) { Digest::MD5.hexdigest(rand.to_s) }
factory :story do
sequence(:title) { |n| "My Cool Story##{n}" }
# Call the sequence here:
token { Factory.next(:random_token) }
description { "#{title} description"}
end
end
Now, when I try that approach - I get a deprecation warning telling me:
WARNING: FactoryGirl::Sequence#next is deprecated.
Use #run instead.
When I replace #next with #run, I get a no-method error.
I can't find the new syntax in any of the docs... Can anyone point me in the right direction?
Thanks
I think you should use Factory.create(...) instead, e.g.
token { Factory.create(:random_token) }
All I'm trying to do is spec how a one line helper method for a view should behave, but I'm not sure what kind of mock object, (if any) I should be creating if I'm working in Rails.
Here's the code for events_helper.rb:
module EventsHelper
def filter_check_button_path
params[:filter].blank? ? '/images/buttons/bt_search_for_events.gif' : '/images/buttons/bt_refine_this_search.gif'
end
end
And here's my spec code, in events_helper_spec.rb:
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe EventsHelper do
#Delete this example and add some real ones or delete this file
it "should be included in the object returned by #helper" do
included_modules = (class << helper; self; end).send :included_modules
included_modules.should include(EventsHelper)
end
it "should return the 'refine image search' button if a search has been run" do
# mock up params hash
params = {}
params[:filter] = true
# create an instance of the class that should include EventsHelper by default, as the first test has verified (I think)
#event = Event.new
# call method to check output
#event.filter_check_button_path.should be('/images/buttons/bt_search_for_events.gif')
end
end
When I've looked through the docs here - http://rspec.info/rails/writing/views.html, I'm mystified as to where the 'template' object comes from.
I've also tried looking here, which I thought would point me in the right direction, but alas, no dice. http://jakescruggs.blogspot.com/2007/03/mockingstubbing-partials-and-helper.html
What am I doing wrong here?
Thanks,
Chris
You are not doing anything in that spec, just setting a stub, so it will pass, but hasn't tested anything.
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe EventsHelper do
it "should return the 'refine image search' button if a search has been run" do
# mock up params hash
params = {:filter => true}
helper.stub!(:params).and_return(params)
helper.filter_check_button_path.should eql('/images/buttons/bt_search_for_events.gif')
end
end
I'm running my test without spec_helper (Ruby 1.9)
require_relative '../../app/helpers/users_helper'
describe 'UsersHelper' do
include UsersHelper
...
end
Ah,
I asked this question on the rspec mailing list, and one kind soul (thanks Scott!) explained to me that there's a handy helper object for this, that you should use instead, like so:
Rails has its own helper function
params = {:filter => true}
helper.stub!(:params).and_return(params)
I've now updated the code like so:
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe EventsHelper do
#Delete this example and add some real ones or delete this file
it "should be included in the object returned by #helper" do
included_modules = (class << helper; self; end).send :included_modules
included_modules.should include(EventsHelper)
end
it "should return the 'refine image search' button if a search has been run" do
# mock up params hash
params = {}
params[:filter] = true
helper.stub!(:filter_check_button_path).and_return('/images/buttons/bt_search_for_events.gif')
end
end
And it's working. Huzzah!