Hi Renzo,
I'm working on JBehave in my spare time, so the whole BDD thing is very
big for me. I'd like to make a suggestion which I think will help you to
understand the paradigm shift better.
For clarity, here's a summary of your methods:
shouldAddToListImpl
shouldCallSizeAndHaveSizeOfOne
shouldFoundStarWars
But these aren't descriptive of the behaviour of the class - they're named
after the acceptance criteria. To describe the behaviour of the class
better, I'd call them:
shouldBeEmptyWhenFirstCreated
shouldHaveASizeEqualToTheNumberOfItemsAdded
shouldProvideAnIteratorOverAnyItemsAdded
etc.
You might add one item and expect to see a size of 1, but that's not the
behaviour you're designing; it's just one way that you can specify an
acceptance criteria for that behaviour. By naming the methods after the
behaviour, not the acceptance criteria, it's easier to see how the class
should perform and what its responsibilities are. I don't think it really
matters whether you use mocks, stubs or the real code here, nor do I think
it matters whether you add one, two or three items, as long as you can
verify, when you're done, that the class behaves as expected.
Does this help describe the shift in thinking of BDD?
Thank you for posting this, BTW. I've been telling everyone that you can
try out BDD by using "should" instead of "test", and the rest will
automatically follow; now I can see that it isn't true at all. I guess
I've always thought in terms of BDD, which is why I'm so passionate about
it, but it makes it very hard for me to understand why people "don't get
it" (or indeed, what it is that they "don't get").
Your example has illuminated my problem and given me new insight. I hope
I've helped with yours.
Regards,
Liz.
--
Elizabeth Keogh
ekeogh@...
http://www.livejournal.com/users/sirenian
extremeprogramming@yahoogroups.com wrote on 30/09/2005 11:16:48:
> Well, I've read the paper. Thank you for pointing out the focus shift
> from "verification" to "specification". Anyway what I'm seeing here
> is a shift in the way to write state tests instead of a paradigm shift.
>
> Maybe I'm wrong but when I talk about testing behaviour, I'm thinking
> at something closer to mock driven developing, where the "Context" is
> an object instance along with its relationships to other instances
> and the way this network reacts to external stimuli. (for an in-depth
> look here http://www.jmock.org/oopsla2004.pdf for example).
>
> Now, why not to use the shift in writing test cases that Dave is
> describing to do mock behavioural testing? What I'm saying is that
> for example:
>
> class OneMovieList < Spec::Context
> def setup
> @list = MovieList.new
> star_wars = Movie.new "Star Wars"
> @list.add star_wars
> end
> def should_have_size_of_1
> @list.size.should_equal 1
> end
> def should_include_star_wars
> @list.should_include "Star Wars"
> end
> end
>
> is roughly equivalent in Java/Junit (sorry I don't know Ruby :) to:
>
> class OneMovieList extends Context {
> MovieList _movieList;
> void setUp() {
> _movieList=new MovieList();
> _movieList.add("Star Wars");
> }
> public void shouldHaveSizeOfOne() {
> shouldEqual(1, _movieList.size());
> }
> public void shouldIncludeStarWars() {
> shouldInclude("Star Wars", _movieList.iterator());
> }
> }
>
> that seems to me plain old state testing written with a different
> (and clearer) syntax. Now, what about this:
>
> class OneMovieList extends Context {
> MovieList _movieList;
> ArrayList _movieListMockImpl;
> void setUpState() {
> _movieList=new MovieList();
> _movieListMockImpl=mock(MovieListImpl.class);
> _movieListMockImpl.forwardTo(new ArrayList());
> _movieList.setListImpl(_movieListMockImpl);
> _movieList.add("Star Wars");
> _movieList.size();
> _movieList.contains("Star Wars");
> }
> public void shouldAddToListImpl() {
> shouldReceiveMessage("add", _movieListMockImpl).once();
> }
> public void shouldCallSizeAndHaveSizeOfOne() {
> shouldReceiveMessage("size", _movieListMockImpl).andReturn(1);
> }
> public void shouldFoundStarWars() {
> shouldReceiveMessage("contains", _movieListMockImpl)
> .with("Star Wars").andReturn(true);
> }
>
> In my opinion, the last OneMovieList class does behavioural testing
> as well as state tesing (and you can choose how deep to go with any
> of them). Just some thoughs.
>
> Bye
> Renzo
[Non-text portions of this message have been removed]