How do I unit test the following:
def update_config
store = YAML::Store.new('config.yaml')
store.transaction do
store['A'] = 'a'
end
end
Here is my start:
def test_yaml_store
mock_store = flexmock('store')
mock_store
.should_receive(:transaction)
.once
flexmock(YAML::Store).should_receive(:new).returns(mock_store)
update_config()
end
How do I test what is inside the block?
UPDATED
I have converted my test to spec and switched to rr mocking framework:
describe 'update_config' do
it 'calls transaction' do
stub(YAML::Store).new do |store|
mock(store).transaction
end
update_config
end
end
This will test the transaction was called. How do I test inside the block: store['A'] = 'a'
?
First, you can write this a little simpler -- your test using RR isn't a direct port of your test using FlexMock. Second, you're not testing what happens within the block at all so your test is incomplete. Try this instead:
describe '#update_config' do
it 'makes a YAML::Store and stores A in it within a transaction' do
mock_store = {}
mock(mock_store).transaction.yields
mock(YAML::Store).new { mock_store }
update_config
expect(mock_store['A']).to eq 'a'
end
end
Note that since you're providing the implementation of #transaction, not merely the return value, you could have also said it this way:
describe '#update_config' do
it 'makes a YAML::Store and stores A in it within a transaction' do
mock_store = {}
mock(mock_store).transaction { |&block| block.call }
mock(YAML::Store).new { mock_store }
update_config
expect(mock_store['A']).to eq 'a'
end
end
You want to call yields:
describe 'update_config' do
it 'calls transaction which stores A = a' do
stub(YAML::Store).new do |store|
mock(store).transaction.yields
mock(store).[]=('A', 'a')
end
update_config
end
end
Check out this answer for a different approach to a related question. Hopefully the rr api documentation will improve.