[rspec-devel] huge setup methods? I think I'm on the wrong path

David Chelimsky dchelimsky at gmail.com
Wed Jan 24 15:40:36 EST 2007


On 1/24/07, Jens-Christian Fischer <jcfischer.lists at gmail.com> wrote:
> I'm relatively new to RSpec and am still struggling with some basics:
>
> Consider the following view spec:
>
> context "Given a request to render rooms/show" do
>    setup do
>      @room = mock("room")
>      @room.stub!(:name).and_return("Liftchat")
>      @message = mock("message")
>      @messages = [@message]
>      @u1 = mock("user1")
>      @u2 = mock("user2")
>      @u1.stub!(:nickname).and_return("jcfischer")
>      @u2.stub!(:nickname).and_return("lau")
>      @u1.stub!(:active?).and_return(true)
>      @u2.stub!(:active?).and_return(false)
>      @u1.stub!(:style).and_return("")
>      @u2.stub!(:style).and_return("")
>      @u1.stub!(:id).and_return(1)
>      @u2.stub!(:id).and_return(2)
>
>      users = [@u1, @u2]
>      @room.stub!(:users).and_return(users)
>      admins = [@u1]
>      @room.stub!(:admins).and_return(admins)
>      @room.stub!(:is_admin?).and_return(true)
>      @message.stub!(:user).and_return(@u1)
>      @message.stub!(:msg).and_return("bla")
>      @message.stub!(:id).and_return(1)
>      @room.stub!(:messages).and_return(@messages)
>      assigns[:room] = @room
>      assigns[:messages] = @messages
>    end
>
>    specify "should dispaly the userlist" do
>
>      render 'rooms/show'
>      #response.should_have "h1", :text => "Liftchat"
>      #response.should_have "ul[id=users]"
>      response.should_have "li>a", :text => "jcfischer"
>      response.should_have "li>a", :text => "lau"
>    end
>
> end
>
> It seems to me, that I'm doing something completely stupid, because
> my setup method is growing and growing, stubbing every method call
> that my views are making. Is this supposed to look like this or am I
> missing something completely obvious?

If the view needs to ask a lot of questions, then your setup is going
to look something like that. You can, though, clean things up a little
bit:

context "Given a request to render rooms/show" do
  def create_user(name, active, style, id)
    user = mock(name)
    user.stub!(:nickname).and_return(name)
    user.stub!(:active?).and_return(active)
    user.stub!(:style).and_return(style)
    user.stub!(:id).and_return(id)
  end

  setup do
    @u1 = create_user("jcfischer", true, "", 1)
    @u2 = create_user("lau", false, "", 2)
    ...

Another thing you can do is to tell the mock to act like a Null Object
[GOF], like so:

user = mock("user", :null_object => true)

This will cause the mock to ignore calls that it isn't interested in,
so you won't get failures by sending messages. If, however, your view
has any trainwrecks in it (user.address.zipcode), then you'd have to
supply something specific to return for address.

The other thing is that, since you're really using a stub (i.e. the
verification is that the right stuff shows up in the tags), you could
use OpenStruct:

require 'ostruct'

context "...." do
  specify "..." do
    @u1 = OpenStruct.new(:name => "jcfischer", :etc => "otherstuff")
  end
  ...

Hope that helps.
David

>
> thanks
> jc
> _______________________________________________
> rspec-devel mailing list
> rspec-devel at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-devel
>


More information about the rspec-devel mailing list