Learning StoryRunner
Posted by jacqui maher on January 06, 2008 at 02:53 PM
in which I try to get done with my mockamator already by writing stories describing what it should do, learning how to work with Story Runner in RSpec along the way.
references:
* What’s in a Story by Dan North
* Great step by step example driven tutorial for Rspec on story runner
* RSpec docs on mock objects
This is my first attempt at a story. I already find this helpful as it forces me to make decisions and figure out what it is, exactly, that I’m trying to accomplish. And how.
The Nelson plugin should automagically create mocks (valid or invalid) for any given controller
Narrative:
As a developerI want to easily write controller specs
So that I’m not spending hours on hundreds of LOC making mocks with the right expectations
Acceptance Criteria:
Scenario 1: writing a new controller specGiven the UserController
And that I want to use valid mocks that won’t throw errors
When calling Nelson.generate_mocks(UserController, {:valid => true})
Then a site instance object should be mocked out
And a get request, for example, on the signup form should not raise an error
Ok, so that’s my story and it’s useful in that it’s already helped me get a better idea of what I’m doing… but how do I translate this into Ruby code that can be run through rspec?
One of the tutorials I’m following gives an example of a story, so I am just going to copy and paste it and change it to be appropriate for my narrative:
1 Story "The Nelson plugin", %{
2 should automagically create mocks
3 that are valid or invalid
4 for any given controller
5 }, :type => RailsStory do
6
7 Scenario "in the before block of a controller spec" do
8 When "calling Nelson.generate_mocks" do
9 Nelson.generate_mocks(UserController, {:valid => true})
10 end
11
12 Then "a site mock should be generated" do
13 @site.should_not be_nil
14 @site.should be_a_kind_of(Site)
15 end
16
17 When "I request the UserController signup action in a get request" do
18 get '/user/signup'
19 end
20
21 Then "response should be successful" do
22 response.should be_success
23 end
24 end
25 end
That was my first attempt. While writing this a few questions came up, namely…
- does the context get preserved between different When events? that is, will instance variables that are created in one event be accessible in a subsequent event context?
- am i breaking up my tasks correctly?
- what’s up with that array of phrases in the Story block anyway?
- does the When have to be mapped to a controller request?
(from the vaporbase.com tutorial: “The “When” clause is the meat of the scenario. It is a controller action, and its spec gets done next… “)
Only one way to find out: time to run this through the story runner. I foresee some errors… :)
1 jm:~/se/app/workspace (master) $ ruby stories/nelson_should_create_mocks.rb
2 Running 1 scenarios
3
4 Story: The Nelson plugin
5
6
7 should automagically create mocks
8 that are valid or invalid
9 for any given controller
10
11
12 Scenario: in the before block of a controller spec
13
14 When calling Nelson.generate_mocks (FAILED)
15
16 Then a site mock should be generated (SKIPPED)
17
18 When I request the UserController signup action in a get request
19
20 Then response should be successful
21
22 1 scenarios: 0 succeeded, 1 failed, 0 pending
23
24 FAILURES:
25 1) The Nelson plugin (in the before block of a controller spec) FAILED
26 NoMethodError: undefined method `generate_mocks' for Nelson:Class
27 stories/nelson_should_create_mocks.rb:28:in `calling Nelson.generate_mocks'
28 stories/nelson_should_create_mocks.rb:27
29 stories/nelson_should_create_mocks.rb:20
Whoa! That actually went a lot better than I expected. I haven’t written the method “generate_mocks” in my plugin yet, so naturally it would fail.
I love the output of the Story Runner. I think I might be sold. Time to write the methods in my Nelson plugin that will generate the mocks, I guess.
I’ll be posting my stories - when they’re closer to being finalized - here as examples for other people to reference.
In the meantime, here are some:
* from pastie
* from evang.eli.st (scroll down)
* plain text stories from david chelimsky’s blog