I wrote a unit test for a method that writes to stdout. I got it to
work, but I’m not sure my approach was the best. Is there a more
recommended way to do this?
# Create a String with a singleton write method
# that allows it to take the place of stdout.
actual = '''
def actual.write(data); self << data; end
old_stdout, $stdout = $stdout, actual
# Invoke method to test that writes to stdout.
$stdout = old_stdout # restore stdout
On Mar 24, 2006, at 7:50 AM, Mark V. wrote:
I wrote a unit test for a method that writes to stdout. I got it to
work, but I’m not sure my approach was the best. Is there a more
recommended way to do this?
# Create a String with a singleton write method
# that allows it to take the place of stdout.
actual = '''
def actual.write(data); self << data; end
See the standard library, StringIO.
James Edward G. II
On 3/24/06, James Edward G. II [email protected] wrote:
See the standard library, StringIO.
Thanks! I have that working, but it’s not clear to me how that is
better. In fact, it seems to take more code to do it that way. I now
have this.
require ‘stringio’
sio = StringIO.new
old_stdout, $stdout = $stdout, sio
Invoke method to test that writes to stdout.
$stdout = old_stdout # restore stdout
actual = sio.string
Am I overcomplicating this?
On 3/24/06, Mark V. [email protected] wrote:
actual = '''
sio = StringIO.new
I made a benchmark of both solutions, but I was surprised how small the
difference was.
StringIO is faster, as I expected. See below for results.
Apart from that I feel that stringio will have adavantages for giving
you a
complete API.
But for a quick solution the singleton method seems elegant and I like
it a
lot, after all
you do not require( which was not benchmarked!!!) ‘stringio’ and run a
core
script.
But for reusable code I’ll defenitely go for stringio.
Cheers
Robert
---------------------------------- 8<
cat stringio.rb;ruby stringio.rb
#!/usr/bin/env ruby
Create a String with a singleton write method
that allows it to take the place of stdout.
require ‘benchmark’
require ‘stringio’
n = 500000
r1 = r2 = nil
Benchmark.bm do
|bm|
bm.report “single string” do
actual = ‘’
def actual.write(data); self << data.to_s; end
old_stdout, $stdout = $stdout, actual
n.times{ |i| $stdout.write i }
$stdout = old_stdout
r1= actual
end # do
bm.report "stringio " do
sio = StringIO.new
old_stdout, $stdout = $stdout, sio
n.times{ |i| $stdout.write i}
# Invoke method to test that writes to stdout.
$stdout = old_stdout # restore stdout
r2 = sio.string
end # do
end # do
raise Exception unless r1 == r2
user system total real
single string 1.460000 0.000000 1.460000 ( 1.823057)
stringio 1.320000 0.010000 1.330000 ( 1.828039)
–
Deux choses sont infinies : l’univers et la bêtise humaine ; en ce qui
concerne l’univers, je n’en ai pas acquis la certitude absolue.
On Mar 24, 2006, at 8:12 AM, Mark V. wrote:
def actual.write(data); self << data; end
See the standard library, StringIO.
Thanks! I have that working, but it’s not clear to me how that is
better. In fact, it seems to take more code to do it that way.
You originally asked:
Is there a more recommended way to do this?
I was just trying to answer that question.
I prefer the StringIO method because it is a full mock API, as Robert
Dober said. However, if you know you will only need the one method
(now and forever?!) there is probably little difference.
James Edward G. II