I think your approach with an interface would work, and I don't think I would make use of events. Assuming the application does not accept user input other than command line parameters, I would probably use something like this to wrap Console.Write/Console.WriteLine
:
public interface IConsoleWriter
{
void Write(string format, params object[] args);
void WriteLine(string format, params object[] args);
}
To test, I would either create a TestConsoleWriter
that would store all writes into a buffer that I could then assert against, or I would create a mock and verify that Write
or WriteLine
was called with the parameters I expected. If your application is going to be doing a ton of writing to the console (say +100 MB or so of output), then using a mock would probably be preferable for performance reasons, but otherwise I would say pick whichever method you think would be easier to work with.
This approach does have a few limitations, however. If you are using any assemblies that you cannot modify and they write to the console, then you won't see that output since you can't force those classes to use your IConsoleWriter
. Another problem is that the Write
and WriteLine
methods have 18 or so overloads, so you may be wrapping alot of methods. To get around these limitations, you may just want to use the Console.SetOut
method to redirect the console output to your own TextWriter
while testing.
Personally, I think I would take the SetOut
approach. It would just be one line you have to add at the beginning of your unit tests (or possibly in a SetUp
method) and you can just assert against what is written into the TextWriter
.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…