Question

If I have a method like this:

require 'tweetstream'

# client is an instance of TweetStream::Client
# twitter_ids is an array of up to 1000 integers
def add_first_users_to_stream(client, twitter_ids)
    # Add the first 100 ids to sitestream.
    client.sitestream(twitter_ids.slice!(0,100))

    # Add any extra IDs individually.
    twitter_ids.each do |id|
        client.control.add_user(id)
    end

    return client
end

I want to use rspec to test that:

  • client.sitestream is called, with the first 100 Twitter IDs.
  • client.control.add_user() is called with the remaining IDs.

The second point is trickiest for me -- I can't work out how to stub (or whatever) a method on an object that is itself a property of an object.

(I'm using Tweetstream here, although I expect the answer could be more general. If it helps, client.control would be an instance of TweetStream::SiteStreamClient.)

(I'm also not sure a method like my example is best practice, accepting and returning the client object like that, but I've been trying to break my methods down so that they're more testable.)

Était-ce utile?

La solution

This is actually a pretty straightforward situation for RSpec. The following will work, as an example:

describe "add_first_users_to_stream" do
  it "should add ids to client" do

    bulk_add_limit = 100
    twitter_ids = (0..bulk_add_limit+rand(50)).collect { rand(4000) }
    extras = twitter_ids[bulk_add_limit..-1]

    client = double('client')
    expect(client).to receive(:sitestream).with(twitter_ids[0...bulk_add_limit])

    client_control = double('client_control')
    expect(client).to receive(:control).exactly(extras.length).times.and_return(client_control)
    expect(client_control).to receive(:add_user).exactly(extras.length).times.and_return {extras.shift}

    add_first_users_to_stream(client, twitter_ids)

  end
end
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top