I have some functionality, which depends on command line arguments, and different arguments should lead to different results.
I can't directly "simulate" this arguments, since there are some sort of chain dependencies - I need to unit-test some xaml control, which depends on view-model, which depends on certain additional class, which fetches command line arguments using Environment.GetCommandLineArgs
, and I can't directly impact on this last class to set arguments manually instead of using GetCommandLineArgs
.
So, I'd like to know, is there any way to make Environment.GetCommandLineArgs
return value I want it to return, for certain unit-test.
It is possible to pass custom command line arguments to the test module.
option. You can test command line arguments by running an executable from the "Command Prompt" in Windows or from the "DOS prompt" in older versions of Windows. You can also use command line arguments in program shortcuts, or when running an application by using Start -> Run.
Yes, We can pass command line arguments to a test execution by using -D JVM command-line options as shown below.
Description. The ARG( ) function returns the string value of one of the arguments specified in the operating system command that launched the session. The numeric expression position indicates which argument is to be returned.
You need to abstract Environment.GetCommandLineArgs
or what ever is eventually calling it behind something you can mock
public interface ICommandLineInterface {
string[] GetCommandLineArgs();
}
Which can eventually be implemented in a concrete class like
public class CommandInterface : ICommandLineInterface {
public string[] GetCommandLineArgs() {
return Environment.GetCommandLineArgs();
}
}
And can be Tested using Moq
and FluentAssertions
[TestMethod]
public void Test_Should_Simulate_Command_Line_Argument() {
// Arrange
string[] expectedArgs = new[] { "Hello", "World", "Fake", "Args" };
var mockedCLI = new Mock<ICommandLineInterface>();
mockedCLI.Setup(m => m.GetCommandLineArgs()).Returns(expectedArgs);
var target = mockedCLI.Object;
// Act
var args = target.GetCommandLineArgs();
// Assert
args.Should().NotBeNull();
args.Should().ContainInOrder(expectedArgs);
}
Since you are dealing with environment variables, why don't we wrap the outside dependencies into one EnvironmentHelper class, then inject the dependencies?
Here is my suggestion:
public class EnvironmentHelper
{
Func<string[]> getEnvironmentCommandLineArgs;
// other dependency injections can be placed here
public EnvironmentHelper(Func<string[]> getEnvironmentCommandLineArgs)
{
this.getEnvironmentCommandLineArgs = getEnvironmentCommandLineArgs;
}
public string[] GetEnvironmentCommandLineArgs()
{
return getEnvironmentCommandLineArgs();
}
}
Here is the Mock method:
public static string[] GetFakeEnvironmentCommandLineArgs()
{
return new string[] { "arg1", "arg2" };
}
In your source code:
EnvironmentHelper envHelper = new EnvironmentHelper(Environment.GetCommandLineArgs);
string[] myArgs = envHelper.GetEnvironmentCommandLineArgs();
In your unit test code:
EnvironmentHelper envHelper = new EnvironmentHelper(GetFakeEnvironmentCommandLineArgs);
string[] myArgs = envHelper.GetEnvironmentCommandLineArgs();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With