[rspec-users] testing behaviour or testing code?

Zach Dennis zach.dennis at gmail.com
Fri Aug 24 10:08:16 EDT 2007


On 8/24/07, David Green <justnothing at tiscali.co.uk> wrote:
>
> hypothetical question for all you BDD experts:
>
> I want to make sure that a :list action always returns widgets in
> alphabetical order. There's at least 2 ways of doing this:
>
>
> it "should fetch items in alphabetical order" do
>   Widget.should_receive(:find).with(:order => "name ASC")
>   get :list
> end
>
> it "should fetch items in alphabetical order" do
>   [:red, :green, :blue].each {|x| Widget.create(:name => x) }
>   get :list
>   assigns[:widgets].first.name.should == 'blue'
>   assigns[:widgets].last.name.should == 'red'
> end
>
> with the first method, I get to mock the important calls and stub the rest,
> but the example is very closely tied to the implementation. If I change from
> Widget.find to Widget.find_alphabetically then the example breaks (assuming
> find_alphabetically() doesn't use AR::Base.find)
>
> with the second method, I'm testing the behaviour more than how it's
> implemented. I don't care what the action does as long as it gives me an
> array of widgets sorted alphabetically, but I spend more time setting things
> up and worrying about model validations. In addition, the specs are tied to
> a db.
>
> so which is the better method, and is there another way i havn't considered
> that gives me the best of both worlds?

In your controller have something like:

    @widgets = mock("widgets")
    Widget.should_receive(:find_alphabetically).and_return(@widgets)
    get :index

You don't care in your controller test what actually gets returned,
just that it's calling the right method on the model. Now in your
"Widget" spec have one that looks like:

    describe Widget, "#find_alphabetically) do
         before do
             Widget.destroy_all
             # create some widgets for your test, say widgets C, A, B
in that order
             @results = Widget.find_alphabetically
         end

         it "has widget A as the first widget" do
             # ...
         end

         it "has widget B as the second widget" do
             # ...
         end

         it "has widget C as the third widget" do
             # ...
         end
    end

HTH,

Zach


More information about the rspec-users mailing list