On 10/19/07, Daniel Tenner <[EMAIL PROTECTED]> wrote:
> > If I read correctly, Daniel is suggesting that this is not behaviour
> > because he's equating behaviour with interaction. This example checks
> > an outcome, not an interaction.
> >
>
> That's right, one of my axioms is that "specifying" involves
> behaviour/interaction, not state/outcome.

To be honest, I think you're way off the mark.  Objects behave in two
ways: they manipulate their state, or they interact with other
objects.  Both are valid types of behavior and can be used for
specification.

There's a more subtle problem with your argument though, and that's
that as far as specs are concerned, there is no state!

Example:

# given
@account = Account.new 500

# when
@account.withdraw 300

# then
@account.balance.should == 200

The behavior of this object is quite simple.  However, do we know
anything about the implementation?  Do we care to know?

You might reasonably think Account is implemented as
class Account
  attr_reader :amount

  def initialize(balance = 0)
    @balance
  end

  def withdraw(amount)
    @balance -= amount
  end
end

You'd be wrong though.  It's actually implemented as
class Account
  def initialize(balance = 0)
    Transaction.new self, balance
  end

  def withdraw(amount)
    Transaction.new self, -amount
  end

  def balance
    Transaction.for(self).inject(0) { |sum, t| sum += t.amount }
  end
end

(that's the beauty of mailing list examples - I'm always right! :)

Calling withdraw doesn't reduce the account balance.  It reduces the
balance reported by the account.  It's a subtle distinction, and one
that's not important to think about 99% of the time.  Hopefully though
you see why it's a fallacy to discount state-based testing as a valid
specification technique.  As long as you're using an object's API, and
not digging into it's internal state as in David's evil example,
you're dealing with behavior.

Pat
_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to