Bokhari
Bokhari

Reputation: 103

C# Unit Test for Main Method - Manipulating Command Line Arguments - Microsoft Visual Studio Test Tools

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

Answers (2)

Konrad Kokosa
Konrad Kokosa

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:

  1. In your unit test project, from References, right click System and select Add Fakes Assembly
  2. In the new file mscorlib.fakes which will be created, add in section Fakes:

    <ShimGeneration>
      <Add FullName="System.Environment"/>
    </ShimGeneration>
    
  3. Rebuild

  4. 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

Mel
Mel

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

Related Questions