Mrunal Gosar Mrunal Gosar - 1 month ago 21
Java Question

JBehave how to persist objects state between steps

I am using JBehave for writing BDD Integration tests.

Problem: JBehave clears state of objects (instance variables) while executing individual steps

Code:
StepDefinition:

public class StepDefs {

private String str;

@Given("step represents a precondition to an $event")
public void given(String event){
str=event;
System.out.println("Given: "+str);
}

@When("step represents the occurrence of the event")
public void when() {
System.out.println("When: "+str);
}

@Then("step represents the outcome of the event")
public void then() {

}
}


Story:

Sample story

Narrative:
In order to communicate effectively to the business some functionality
As a development team
I want to use Behaviour-Driven Development

Scenario: A scenario is a collection of executable steps of different type
Given step represents a precondition to an event
When step represents the occurrence of the event
Then step represents the outcome of the event


JBehaveJUnitTestRunner:

@RunWith(JUnitReportingRunner.class)
public class JBehaveTestsRunner extends JUnitStories {

private CrossReference xref = new CrossReference();

public JBehaveTestsRunner() {
configuredEmbedder().embedderControls().doGenerateViewAfterStories(true).doIgnoreFailureInStories(true)
.doIgnoreFailureInView(true).doVerboseFailures(true);// .useThreads(1);
}

@Override
public Configuration configuration() {
Properties viewResources = new Properties();
viewResources.put("decorateNonHtml", "true");
return new MostUsefulConfiguration().useStoryLoader(new LoadFromClasspath(this.getClass().getClassLoader()))
.useStoryReporterBuilder(
new StoryReporterBuilder().withFormats(Format.HTML, Format.CONSOLE, Format.STATS)
.withViewResources(viewResources).withFailureTrace(true).withFailureTraceCompression(false)
.withCrossReference(xref));
}

@Override
public InjectableStepsFactory stepsFactory() {
return new ScanningStepsFactory(configuration(), "stepdefs");
}

@Override
public List<String> storyPaths() {
StoryFinder finder = new StoryFinder();
return finder.findPaths(CodeLocations.codeLocationFromClass(getClass()), Arrays.asList("**/Simple.story"), null);
}
}


Actual Output:

Processing system properties {}
Using controls EmbedderControls[batch=false,skip=false,generateViewAfterStories=true,ignoreFailureInStories=true,ignoreFailureInView=true,verboseFailures=true,verboseFiltering=false,storyTimeouts=300,threads=1,failOnStoryTimeout=false]

(BeforeStories)

Running story stories/Simple.story
Sample story
(stories/Simple.story)
Narrative:
In order to communicate effectively to the business some functionality
As a development team
I want to use Behaviour-Driven Development
Scenario: A scenario is a collection of executable steps of different type
**Given: event**
Given step represents a precondition to an event
**When: null**
When step represents the occurrence of the event
Then step represents the outcome of the event



(AfterStories)

Generating reports view to 'C:\WORKING\lunaworkspace\pkeautomation\target\jbehave' using formats '[html, console, stats, junitscenarioreporter]' and view properties '{decorateNonHtml=true}'
log4j:WARN No appenders could be found for logger (freemarker.cache).
log4j:WARN Please initialize the log4j system properly.
Reports view generated with 3 stories (of which 1 pending) containing 2 scenarios (of which 1 pending)


As can be seen in the output: In the Given step I am accepting a string argument which i am initializing it to instance variable "str", whilst printing the value to console I can see it successfully. But when the second step i.e When step executes I am getting null as the value of instance variable "str". How can I make JBehave to not clear state of objects after executing individual steps?

Answer

For anyone coming looking for an answer for this question I did found proper resolution to this by taking help from the JBehave google group community. The solution is quite simple instead of using ScanningStepFactory Use InstanceStepsFactory and that should persist the state of the objects. Link to the discussion: Google Group discussion