Test Doubles - Stubs with Constraints

This topic is for the [Stubs with Constraints][] exercise in the [Test Doubles][] trail. Post any questions, corrections, or pointers you have to share with other Upcase subscribers.
[Stubs with Constraints]: https://exercises.upcase.com/exercises/stubs-with-constraints
[Test Doubles]: https://thoughtbot.com/upcase/test-doubles

I need a little help with some Ruby syntax. post.rb has ‘def self.visible_to’ which means it’s called with ‘Post.visible_to(user)’.
But in dashboard.rb it’s called with ‘@posts.visible_to(@user)’. Can I get an explanation as to how a class method is being called by an ActiveRecordRelation. (I believe @posts is being set to an ActiveRecordRelation with Post.all.)

It chokes if I @posts is an array, I think visible_to can be called with an ActiveRecordRelation or as a class method.

Thanks in advance!

Hello @flocela. You’ve basically described it, but the workings are that class methods on ActiverRecord classes can act as scopes and can be called on ActiveRecord relations. See the guides section on scopes for more detail.

1 Like

Will look up scopes. Thanks for pointing me in the right direction.

Not really a question about the topic, just FYI for you guys. I just cloned down the exercise repo and the .ruby-version file specifies 2.2.1 — but the Gemfile specifies 2.1.5

So when bin/setup runs bundler, I get a ruby version error.

@sheck thanks for pointing this out. I’ve updated the Gemfile and pushed up to the source repo. Note, this will only affect new users cloning after my change as we keep a pointer to the source commit when you clone.

Thanks!

1 Like

My solution looks like this:

describe Dashboard do
  describe "#posts" do
    it "returns posts visible to the current user" do
      user = create(:user)
      posts = double(posts)
      allow(Post).to receive("visible_to").with(user).and_return(posts)

      dashboard = Dashboard.new(posts: Post.all, user: user)

      expect(dashboard.posts).to eq(posts)
    end
  end
end

It works and I think it’s right but I don’t understand why.

  • Now this is a stub not a mock. Correct?
  • What part of this is exactly the constraint?
  • Under what condition would this test fail?