Having succeeded in getting a simple JBehave story running. my next challenge is to scale it up a bit. In particular, I want to get a JBehave story that integrates with Spring to do something more fully-featured: save an entry in a database.
Because I don’t yet trust JBehave enough to let it drive my application, I’ll back up this with a conventional JUnit test – that will let me know that the story is doing what its meant to do.
To start with, I copied the Simple JBehave scenario from last time, just to get things moving. I then created a simple database app, using a gist I’d prepared a while ago as a template. At this point, the app doesn’t do anything – it’s just a single persistent class.
@Entity @Table
public class Foo {
@Id @GeneratedValue(strategy = AUTO)
private long id;
@Column(length = 50, nullable = false, unique = true)
private String name;
@Column(length = 200, nullable = true)
private String description;
Foo() {
// for hibernate.
}
public Foo(String name) {
this.name = name;
}
public long getId() { return id; }
public String getName() { return name; }
public String getDescription() { return description; }
public void setDescription(String description) { this.description = description; }
}
I want to augment this with a simple service that I’ll write the JBehave story for. So the next step is to create the service.
@Repository
public class FooService {
@Autowired
private SessionFactory sessionFactory;
@Transactional
public void createFoo(String name, String description) {
Foo foo = new Foo(name);
foo.setDescription(description);
sessionFactory.getCurrentSession().save(foo);
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/testContext.xml")
public class FooServiceTest {
@Autowired private FooService test;
@Autowired private JdbcTemplate jdbc;
@After public void cleanData() {
jdbc.execute("truncate schema PUBLIC and commit");
}
@Test public void test() {
assertEquals("we start with no foo", 0, jdbc.queryForInt("select count(*) from foo"));
test.createFoo("foo", "this is a test foo");
assertEquals("we end with one foo", 1, jdbc.queryForInt("select count(*) from foo"));
Map results = jdbc.queryForMap("select * from foo");
assertEquals("foo", results.get("name"));
assertEquals("this is a test foo", results.get("description"));
}
}
Again, this is a really simple test, but it’s a good starting point. I need to make sure that the JBehave test that I write can cover this as well.
(A key thing to note here: the FooServiceTest is not transactional, and doesn’t automatically rollback. This is intentional – it means that I’m testing the transactional semantics of the code. This still counts as a unit test, though, because it’s an in-memory database – deleting all the data is no slower than rolling back the transaction. The JBehave test will need to be able to do the same thing)
Now that we have a working service, it’s time to move on to the JBehave work. Let’s start with the story.
When we create a Foo called 'bar' Then it gets saved in the database with the name 'bar'
And the Story and Steps:
</pre>
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/testContext.xml")
public class FooServiceStory extends JUnitStory {
@Autowired private ApplicationContext context;
@Autowired private JdbcTemplate jdbc;
@After public void cleanData() {
jdbc.execute("truncate schema PUBLIC and commit");
}
@Override public Configuration configuration() {
return new MostUsefulConfiguration();
}
@Override public List<CandidateSteps> candidateSteps() {
return new SpringStepsFactory(configuration(), context).createCandidateSteps();
}
}
@Component
public class FooServiceSteps {
@Autowired private FooService test;
@Autowired private JdbcTemplate jdbc;
@When("we create a Foo called 'bar'")
public void createFoo() {
test.createFoo("foo", "this is a test foo");
}
@Then("it gets saved in the database with the name 'bar'")
public void lookForFoo() {
assertEquals("we end with one foo", 1, jdbc.queryForInt("select count(*) from foo"));
}
}
Again, this is kind of brain-dead simple, but it works. The feedback from running the test inside the IDE is pretty poor, but I can make the test pass or fail by changing the assertion. So, at this point, I’ve got a Spring-enabled JBehave test.
One part that should be explained is the candidateSteps() method. This is the method used by the JUnitStory super-class to find the step classes. The SpringStepsFactory is a JBehave class that knows how to use a Spring ApplicationContent – it looks through all the beans defined in the context to see if they have JBehave annotations on them.
That’s where I’m leaving it for now. In the next instalment, I want to make this be based off JBehave’s own infrastructure for Spring, as opposed to leveraging the JUnit stuff. It’s my sincere hope that going that way I can improve the in-IDE experience, as well as improve the reporting. I’m a long way from being happy with this right now.
Update: I’ve updated the example to use the SpringStepsFactory class to create the step. This is a better approach – especially if the test shown above was a base class, or if it extended from the JUnitStories class instead.

You should look at the JBehave example on Spring Security – shows how to test Spring-based services (in this case Spring Security AuthenticationManager authenticate method) with JBehave.
Thanks, Brian. My research is running ahead of my blog posts – I have looked at those, and my one of my next posts in this series will be using a similar technique (in particular, using the
SpringStepsFactorydemonstrated there). My next post, though, is going to look at theSpringAnnotatedEmbedderRunner(though I may yet decide to reverse that order… 😉For those playing along at home, the examples can be found at the JBehave Github account
I’ve updated my example to use the SpringStepsFactory, as per the Spring Security example – it is a better approach, and I would probably have got there on the first draft if I didn’t post at 11pm at night. 😉