[rspec-devel] [ rspec-Feature Requests-10285 ] DSL for example execution and non-procedural expectation/state testing

noreply at rubyforge.org noreply at rubyforge.org
Sun Nov 18 21:31:29 EST 2007


Feature Requests item #10285, was opened at 2007-04-22 12:51
You can respond by visiting: 
http://rubyforge.org/tracker/?func=detail&atid=3152&aid=10285&group_id=797

Category: None
Group: None
>Status: Closed
Priority: 3
Submitted By: Simon Nicholls (simon_nicholls)
Assigned to: Nobody (None)
Summary: DSL for example execution and non-procedural expectation/state testing

Initial Comment:
Currently, taking Rails controller testing as an example, this would work for DRY state based testing:

describe SomeController do
  before do
    #mocks and stubs allowing @test to be tested
    get 'test_action'
  end
 
  it "should have good state" do
    @test.should == ""
  end

  #...other state specs
end

But you can't set mock expectations, as the production code execution is in the setup. This is better for expectation style:

describe SomeController do
  before do
    #mocks and stubs, allowing @test to have expectations set
  end

  after do
    get 'test_action'
  end

  it "should call test" do
    @test.should_receive(:test) #etc
  end

  #...other mock expectations
end

Having execution after the specs allows for mock expectations, but then state specs will be jumping the gun.

On top of creating problems if trying to mock and state test together, it doesn't feel right that the actual production code example run has no clear home of it's own.

What I'd like is an optional way to forget ordering of mock expectations and state checking - they are all specs which should be written before running the SUT - and have the execution wrapped in some nice DSL (This would also create a context for further features)

describe SomeController do
  before do
    #mocks and stubs, allowing @test use in specs
  end

  example do
    get 'test_action'
  end

  it "should call test" do
    @test.should_receive(:test) #etc
  end

  it "should have good state" do
    @test.should == ""
  end

end

If "should" and "should_not" state expectations could defer until after the example is run, when mocks are verified, then all would be peachy. DRY specs, and a clear separation of concerns. It seems non-trivial but perhaps possible.

----------------------------------------------------------------------

Comment By: Chad Humphries (spicycode)
Date: 2007-11-19 02:30

Message:
Moved to http://rspec.lighthouseapp.com/projects/5645-rspec/tickets/40-10285-dsl-for-example-execution-and-non-procedural-expectation-state-testing#ticket-40-2

----------------------------------------------------------------------

Comment By: Simon Nicholls (simon_nicholls)
Date: 2007-04-22 16:11

Message:
Yeah, I'm kind of jumping into the deep end here. Just
wanted to throw something out and see what you thought.

I'd be pretty happy with something along the lines of the
2nd version actually, as it does capture the spirit of the spec.

I have some niggly thoughts in my mind about being able to
state a default before/after event to run if not overridden
(using new dsl or hanging off some existing dsl), but I
can't really say if it's needed.

Dude, it's Sunday! Thanks for getting back so quickly! :D

----------------------------------------------------------------------

Comment By: David Chelimsky (dchelimsky)
Date: 2007-04-22 13:49

Message:
As Aslak and Dave and I have all stated emphatically, clarity is king in examples in our view, which means a little moisture is OK if it results in better feedback from reading the examples. I think doing this implicitly would be nothing but confusing to anyone reading the specs trying to understand a failure. When did what run?

There was a similar suggestion to this either in the tracker or on one of the mailing lists that read more like this:

describe SomeController do
  def event
    get 'test_action'
  end

  it "should call test", before_event do
    @test.should_receive(:test) #etc
  end

  it "should have good state", after_event do
    @test.should == ""
  end

end

I'd be more open to something like that which is more explicit. Actually, how about "during_event" for the mock expectation - then you could have this:

  it "should call test", during_event do
    @test.should_receive(:test) #etc
  end

  it "should have good state", after_event do
    @test.should == ""
  end

Now THAT reads really nicely. WDYT?


----------------------------------------------------------------------

You can respond by visiting: 
http://rubyforge.org/tracker/?func=detail&atid=3152&aid=10285&group_id=797


More information about the rspec-devel mailing list