Reputation: 2202
I have a simple script which I'm playing with (a Ruby caesars cypher implementation), none of my methods are written within a Module or Class. How can I write Rspec tests to call these non-instance/class lone type methods?
def cypher(string, factor)
string_array = string.downcase.split('')
...
string_array.each do |item|
...
end
puts cyphered_array_alpha.join
end
Method content omitted for brevity.
Test:
describe "#cypher" do
it "should return characters adjusted by given index" do
expect(cypher("abcd", 1)).to eql('bcde')
end
end
Ive tried using {cypher()}
without any joy.
Upvotes: 0
Views: 425
Reputation: 15248
All Ruby methods are located in specific modules or classes
When you define method on top level you define this method in Object
as private method. Therefore it is available in any object. Usually it is a bad idea
Probably it's better to use some container for your method (class or module) and test this class or module
Also it's better to define method without any output — just return some value. In this case you can use this method anywhere, not only in STDOUT (for example in the web app, telegram bots, etc.)
# lib/caesar_cypher.rb
module CaesarCypher
module_function
def encrypt(string, factor)
end
def decrypt(cypher, key)
end
end
And then
# spec/caesar_cypher_spec.rb
describe CaesarCypher do
describe '.encrypt' do
it 'encrypts string...' do
expect(described_class.encrypt('abcd', 1)).to eq('bcde')
end
end
describe '.decrypt' do
end
end
Upvotes: 2
Reputation: 2202
I've learned – from this helpful RSpec cheatsheet, that there are some less commonly used, more 'advanced' RSpec matchers, one of which; output(...).to_stdout
can be used to evaluate block output. Though not a full explanation of how to test non-instance or class methods (aka a singleton method perhaps?), this matcher worked in my case:
expect {cypher("abcd", 1)}.to output("zabc\n").to_stdout
Upvotes: 1