Error in fake_twitter_spec.rb in Mocks lesson

  1. At 17:55, you get all green, yet I get:
  1) FakeTwitter.search returns an object with a list of results
     Failure/Error: fake = FakeTwitter.search('term')
     NoMethodError:
       undefined method `[]' for nil:NilClass
     # ./lib/fake_twitter.rb:3:in `search'
     # ./spec/lib/fake_twitter_spec.rb:5:in `block (2 levels) in <top (required)>'
     # ./spec/support/searcher.rb:4:in `block (2 levels) in <top (required)>'

It looks like ‘@results[term]’ is not defined in FakeTwitter.search at that time; it had been initialized to an empty array but is now set to @results[term]. It’s obviously some simple mistake but I’ve looked and looked and can’t find it.

Hi @JESii, could you post your FakeTwitter code? It will help us spot what’s going wrong.

Thanks, George; it’s in this pastie.

When you call FakeTwitter.search, the variable @result is nil.
As it’s failing on the first test you can solve this using instead.

I’m not sure, but i think it will help you.

Thanks, Ronald… that’s my issue. In the workshop, Josh changed that from to @results[term] as part of the latest changes and the test passes for him but fails for me. I’ve reviewed the video several times and as far as I can tell I’ve got the same code he does. Obviously that’s not the case, but I can’t find what I missed.

Aha! I wasn’t going nuts. At 23:10 into the video, Josh runs into the same problem… failure depends on the order in which the tests are run and he fixes it with defaults and a clear method.

Suggestion for the class: For something like this, how about adding a note to the video start page describing the issue. I spent at least a couple of hours trying to figure out what I was doing wrong.

1 Like

thanks a lot JESii, I had this problem already around 20min24secs. My integration test search_twitter_spec.rb was not passing because the first scenario ‘searching by a hashtag’ failted. Skipping ahead to 23min10secs, and implementing the self.clear method on FakeTwitter made the test pass.

Man this was driving me crazy! Thank you for posting this in the forum.

I think better to define an accessor method for results:

class FakeTwitter
  def self.search(term)
    OpenStruct.new(results: results[term])
  end

  def self.[]=(key, value)
    results[key] = value.map{|twitter_hash| Twitter::Status.new(twitter_hash.merge(id: 12345)) }
  end
  
  def self.results
    @results ||= {}
  end
  private_class_method :results
end