Sharing data between steps

The best way to write your method for enacting a BDD Step is to have it completely self contained. ie. it doesn’t need to address anything outside itself. But sometimes you want to share data between the steps in a story. For example, you might want to share a reference to a UIView, or you might want to pass the result of some calculation. Simon supports this using two techniques.

First, when steps are in the same class

When Simon goes to run a step in a story, it first checks a cache to see if it already has an instance of the class that contains the implementation for the step. Then, if not found, Simon instantiates the class and stores it in the cache for the next time it is needed. This cache is initiated at the start of each story and cleared at the end of the stories execution.

Why does this cache matter? because it makes it very easy to transfer information from one step method to another if they are in the same class. All you have to do is setup a class variable or property and use it as your normally would.

And when they are in different classes

When dealing with step mappings in different classes though, Simon has to be a little smarter again.

Internally, each story has a local storage area as well. Simon makes this storage area available to you to transfer objects between classes, this avoiding you having to try and wire these classes together manually. As a developer you could programmatically link them together, but it’s much easier to let Simon take the grunt work of managing things and let you get back to writing your code. This storage area is also important in that it lets you organise your step implementation methods according to whatever suits you, and means that commonly used implementations can still talk to more specific ones.

Accessing this storage area is done through two macros:

SIStoreInStory(key, object);
id obj = SIRetrieveFromStory(key);

Here is an example:

File: Communications.stories

Story: Should be able to pass objects between step classes.
Given this class stores abc in the story storage using key def
then this class should be able to retrieve abc from storage with key def

File: CommsASteps.m

@implementation CommsASteps

   SIMapStepToSelector(@"Given this class stores (.*) in the story storage using key (.*)", storesString:withKey:);
   -(void) storesString:(NSString *) aString withKey:(NSString *) key{
      SIStoreInStory(key, aString);
   }
 
@end

File: CommsBSteps.m

@implementation CommsBSteps

   SIMapStepToSelector(@"then this class should be able to retrieve (.*) from storage with key (.*)", retrieveString:withKey:);
   -(void) retrieveString:(NSString *) aString withKey:(NSString *) key{
      NSString *value = SIRetrieveFromStory(key);
      SIAssertObjectEquals(value, aString);
   }

@end

Here’s what happens with the above methods:

  1. Simon instantiates CommsAStep.
  2. CommsAStep reads a key and a value from a step and then stores the value in the story cache so that other objects can access it.
  3. Simon instantiates CommsBStep.
  4. CommsBSteps then reads that value back from the cache and verifies it.

Just in case you are wondering

After each story has finished, Simon clears out the story’s caches – releasing the step implementation instances and generally handles clean up for you. So you cannot transfer data between stories at this time, just between steps. That may come later.

blog comments powered by Disqus

Index

Simon What is BDD? Why Simon?
Installation Quick Start Guide Simon's UI
Writing Stories Mapping Stories Step Conversations Validating Results Accessing your app's UI Exceptions and Errors
The Pieman
Macro reference API reference Simon's CLI args Pieman's CLI args Change Log Thank you BSD License

Download latest
static library
v0.2.0