Reputation: 13568
I am using Mocha and Factory_girl in a JRuby rails application. When I call the factory I would like to return the objects with some mocking already done. Here is a code snippet of what I am trying to do.
Factory.define :tweet_feed_with_tweets, :parent => :tweet_feed do |t|
t.expects(:pull_tweets).returns([Factory.build(:status),Factory.build(:status)])
end
Because I do not want my unit and functional test to actually pull from the twitter API i want to stub the method so it returns what I want. But, this is not working. The object comes back without any stubbing done. Is there a way to actually have stubbing performed on an object created with factory girl before it gets returned to you?
Upvotes: 1
Views: 7599
Reputation: 14750
Callbacks are now available:
Factory.define :tweet_feed_with_tweets, :parent => :tweet_feed do |t|
t.after_build do |tt|
tt.expects(:pull_tweets).returns([Factory.build(:status),Factory.build(:status)])
end
end
Upvotes: 6
Reputation: 3502
Looking at the documentation & source code for factory_girl
, it looks like the object yielded to the block (t
, in your example) is an instance of a Factory
and not an instance of the object you want to construct (the tweet_feed_with_tweets
, in your example). This means that setting an expectation for the pull_tweets
method on t
is setting the expectation on the Factory
instance and not on the object that will be constructed when you call Factory(:tweet_feed_with_tweets)
. I think this explains why your example is not working as you expect.
I may be wrong, but I can't see a way of adding the expectation within the Factory.define
block. You've probably already thought of this, but I think you'd be better off adding the expectation in the test after you've constructed the instance :-
def test_should_do_something
tweet_feed = Factory(:tweet_feed)
tweet_feed.expects(:pull_tweets).returns([Factory.build(:status), Factory.build(:status)])
# test stuff here
end
If you need this in multiple places, you can extract it into a method :-
def test_should_do_something
tweet_feed = build_tweet_feed_with_tweets
# test stuff here
end
private
def build_tweet_feed_with_tweets
tweet_feed = Factory(:tweet_feed)
tweet_feed.expects(:pull_tweets).returns([Factory.build(:status), Factory.build(:status)])
return tweet_feed
end
A couple of other thoughts :-
stubs
was more appropriate than expects
.pull_tweets
method (and any similar methods) into a TwitterAPI
class. That way it wouldn't seem so bad that you need to set up an expectation on the TwitterAPI
in the test.I hope some of that helps.
Upvotes: 1