Reputation: 103
Using Visual studio, I'm writing a unit test for a program already written using .Net framework 2.0. All the usual unit tests are working fine except testing of Main (the entry point to the application). The program's Main method is declared without any String[] being passed as argument. The program processes command line arguments using Environment.getCommandLineArgs() in an associated object. The main program looks like following:
[STAThread]
static void Main()
{
MainProcessor StartProgram = new MainProcessor();
StartProgram.main();
StartProgram = null;
}
and command line arguments are processed in main like:
public void main() {
String [] args = Environment.getCommandLineArgs();
// process arguments
}
Is there any way to manipulate command line arguments from a test method and processing them using Environment.getCommandLineArgs() as mentioned above?
Upvotes: 2
Views: 7458
Reputation: 16878
Note: This is by bad design. MainProcessor
(or its main
method) shoud take (for example, by constructor) parameters passed from Main
arguments.
But still, you can use Fakes
from within Visual Studio if you would be able to switch to version 2013:
System
and select Add Fakes AssemblyIn the new file mscorlib.fakes
which will be created, add in section Fakes
:
<ShimGeneration>
<Add FullName="System.Environment"/>
</ShimGeneration>
Rebuild
In your test you can stub Environment
static method calls:
[TestMethod]
public void TestSomeMethod()
{
using (ShimsContext.Create())
{
ShimEnvironment.GetCommandLineArgs = () => new string[] { "arg1", "arg2" };
// Your test here.
}
}
You can look at this article also.
Regarding Visual Studio 2010, you can use Fakes predecessor named Moles, which is very similar to the above one. Just add it Visual Studio 2010 Moles from Extension Manager. I believe in Moles it will be:
[TestMethod]
public void TestSomeMethod()
{
using (MolesContext.Create())
{
Moles.MEnvironment.GetCommandLineArgs = () => new string[] { "arg1", "arg2" };
// Your test here.
}
}
Upvotes: 2
Reputation: 2385
Rather than pulling the command-line parameters from Environment, why not just take them as arguments to Main?
static void Main(string[] args)
{
}
Now pass those arguments in to your MainProcessor's constructor as well.
static void Main(string[] args)
{
var processor = new MainProcessor(args);
processor.main();
}
If that's all your Main method does, then you can focus your testing on MainProcessor instead. You can also just invoke Program.Main, passing in whatever you want, but since the only thing you can observe is whether or not an exception is thrown, it's not terribly useful as a test.
If, for some reason, the standard handling of "args" were to mysteriously stop working, you have bigger problems... we all do.
Upvotes: 1