psyho / bogus

Fake library for Ruby
Other
359 stars 14 forks source link

Contract tests with stubbed methods of real objects #56

Open adamniedzielski opened 10 years ago

adamniedzielski commented 10 years ago

Using bogus I can stub a method on real object:

user = FactoryGirl.create(:user)
stub(user).friend?(5) { true }

And this works great! However, I would like to use contract tests in such a case. I went through the whole documentation and couldn't find any related example.

Ideally it should work like:

user = fake(:user, FactoryGirl.create(:user)) # creates a named fake from existing object
stub(user).friend?(5) { true }

# in spec/models/user_spec.rb
verify_contract(:user)

Can you show me how to achieve this if it's possible? Or if it's not possible - does it sound like a reasonable feature request?

psyho commented 10 years ago

It's not possible at the moment unfortunately.

I think it's a reasonable feature to have - we would like to support many different coding styles if possible.

However, I'd prefer this type of syntax:

stub(user, as: :author).friend? { true }
stub(user, as: :commenter).logged_in? { true }

# in user_spec.rb
verify_contract(:author)
verify_contract(:commenter)

This would make it easier for a class to play multiple roles, and naming those roles accordingly. Perhaps we could also add a default value to this option - derived from the name of the objects class.

What do you think about doing it this way?

adamniedzielski commented 10 years ago

@psyho - thanks for the quick response! Your syntax is much better than mine.

However, I would avoid default value derived from class name, because this could make it unclear why contract verification is triggered. For example:

stub(user).friend? { true } # no hint that it triggers contract verification

# in user_spec.rb
verify_contract(:user)
psyho commented 10 years ago

You're right - tracking down the missing interactions would be more confusing and difficult if we made it the default behavior. It would also be a breaking change instead of an improvement.

This doesn't look too hard to implement - I should be able to add it in the next release.

adamniedzielski commented 10 years ago

So, I'm waiting for your implementation. If you want some help - just let me know and I will hack a bit and try to make a pull request.