Closed olerass closed 10 years ago
Then clauses (as well as Invariant and And clauses) must be idempotent. That means they need to return the same value every time they are called. This is because parts of the Then expression are reevaluated several times as the subexpressions are printed in the output.
Rewrite your example like this:
describe 'rspec-given' do
context 'fails to give the correct message' do
Given(:str) { '123 789' }
Given(:io) { StringIO.new str }
When(:result) { io.read(3) }
Then { result == '1234' }
end
end
This has the added benefit of emphasizing that it is the io.read call that is being tested, not the StringIO.new.
Of course - you're right. And it even says that in the readme... sorry for the confusion!
No problem.
Just an follow up; actually in the example I don't want to test the io.read call. In reality this is what I'd like to do:
context 'returns an IO wrapping the server message specified' do
When(:msg_io) { TestServerMessage.io :print }
Then { msg_io.getc.ord == 8 } # Type of SVC_Print
And { msg_io.length == 48 } # Length of SVC_Print
end
The UUT is the TestServerMessage.io method. But to test that it actually wraps the correct object in an IO I have to read a byte from it and check if it is what I expect (not idempotent). I also check the length of the IO but that's safe. I'm not sure how to do this with idempotent then
and and
operations only.
Outputs:
But it should be: