From: Nat Pryce Date: 2002-08-19T00:48:07+09:00 Subject: Re: Using Test::Unit to assert messages appeared on $stdout/$stderr On Fri, 2002-08-16 at 20:41, Gray, Jeff wrote: > I'm sorta new to the whole unit testing thing, and my only prior exposure to > software testing is using DejaGnu/Expect. I'm just starting to use > Test::Unit, and I have a case where a certain action should produce a > warning message. There is no other side effect that can be tested to make > sure the condition that produced the warning was indeed exercised properly, > just the appearance of the message. > > I don't see any obvious assertion in Test::Unit that allows checking of I/O > to $stdout/$stderr. What's a good way to test for such a case? If something is hard to test, that's a good indication that the design needs to change. In your case, your object is writing to stdout or stderr. Because it is accessing the output streams through a global variable, you cannot intercept those calls and test that they are correct. A unit test is meant to test a unit (a class, for example) in isolation. That means you have to be able to isolate the unit from its environment, which means it should not read or write global variables. In fact it should only make calls to objects that it has as instance variables or are passed to it's methods as parameters. I would therefore change my design so that the object under test is given a stream object to which it writes messages. In my unit tests, I would pass in a mock stream object that asserts that it is called correctly. In my application and end-to-end functional tests, I would pass in a reference to stdout or stderr so that output actually gets written. I have written a Test::Mock package that you might help you mock the output stream object. You can get it from here: http://www.ruby-lang.org/~knu/cgi-bin/cvsweb.cgi/rough/lib/testmock/ Cheers, Nat. -- Dr. Nathaniel Pryce, Technical Director, B13media Ltd. Studio 3a, 22-24 Highbury Grove, London N5 2EA, UK http://www.b13media.com