Skip to content

Instantly share code, notes, and snippets.

@jamesmartin
Created February 16, 2011 10:13
Show Gist options
  • Save jamesmartin/829140 to your computer and use it in GitHub Desktop.
Save jamesmartin/829140 to your computer and use it in GitHub Desktop.
Simplified illustrative example of 'collaboration' tests between two objects in RSpec
class Account
attr_writer :logger, :username, :password
def logger logger
@logger ||= logger
end
def login
# do authentication stuff...
begin
@logger.log('Invalid login')
rescue
# alternative logging
end
end
end
describe Account do
describe "logging account activity" do
context "when an invalid login attempt is made" do
it "logs the failed attempt" do
logger = double('Logger')
logger.should_receive(:log).with('Invalid login')
account = Account.new
account.logger = logger
account.username = 'invalid'
account.password = 'invalid'
account.login
end
end
context "when its logger encounters a problem" do
it "handles any errors raised" do
logger = double('Logger')
logger.stub(:log).and_raise "Logging unavailable"
account = Account.new
account.logger = logger
account.username = 'irrelevant'
account.password = 'irrelevant'
expect { account.login }.to_not raise_error
end
end
end
end
@jamesmartin
Copy link
Author

These tests focus on the collaboration between the Account and Logger objects, from the perspective of the Account object. At the same time, we're defining an implicit contract between Account and Logger, which we should test separately.

The trick is to keep track of all the, as yet, unimplemented conditions of the contract between all collaborators as we design.

I find these kind of collaboration tests, involving test doubles, guide me towards a clearer separation of concerns and nicer interfaces.

What if RSpec could tell us whenever we use a test double without implementing and/or checking that the real object does what we expect?

Could the proposed Undefined method stub report help us here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment