question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Version 2.4.x System.ArgumentNullException parsing options in unit-test

See original GitHub issue

Hello,

i tried all 2.4.x versions (2.4.0, 2.4.1, 2.4.2, 2.4.3) and all have the same exception. In my unit-test i call my program only with “–help” after that, i receive the following stacktrace:

// Stacktrace
System.ArgumentNullException
Value cannot be null.
Parameter name: element
   at System.Attribute.GetCustomAttributes(Assembly element, Type attributeType, Boolean inherit)
   at System.Reflection.CustomAttributeExtensions.GetCustomAttributes[T](Assembly element)
   at CommandLine.Infrastructure.ReflectionHelper.GetAttribute[TAttribute]()
   at CommandLine.Text.HelpText.AutoBuild[T](ParserResult`1 parserResult, Func`2 onError, Func`2 onExample, Boolean verbsIndex, Int32 maxDisplayWidth)
   at CommandLine.Text.HelpText.AutoBuild[T](ParserResult`1 parserResult, Int32 maxDisplayWidth)
   at CommandLine.Parser.<>c__DisplayClass17_0`1.<DisplayHelp>b__1(IEnumerable`1 _, TextWriter writer)
   at CSharpx.MaybeExtensions.Do[T1,T2](Maybe`1 maybe, Action`2 action)
   at CommandLine.ParserResultExtensions.WithNotParsed[T](ParserResult`1 result, Action`1 action)
   at CommandLine.Parser.DisplayHelp[T](ParserResult`1 parserResult, TextWriter helpWriter, Int32 maxDisplayWidth)
   at Program.<Main>d__5.MoveNext() in C:\..\..\Program.cs:line 33

My code snippets are the following ones:

// Test method (xUnit) which fails
[Fact]
public async Task CallMain_GiveHelpArgument_ExpectSuccess() {
    var result = await Program.Main(new[] { "--help" });

    Assert.Equal(ERROR_SUCCESS, result);
}
// main program
internal class Program {

  private const int ERROR_SUCCESS = 0;

  internal static async Task<int> Main(string[] args) {
      bool hasError = false;
      bool helpOrVersionRequested = false;

      ParserResult<Options> parsedOptions = Parser.Default.ParseArguments<Options>(args).WithNotParsed(errors => {
          helpOrVersionRequested = errors.Any(x => x.Tag == ErrorType.HelpRequestedError || x.Tag == ErrorType.VersionRequestedError);
          hasError = true;
      });

      if (helpOrVersionRequested) {
          return ERROR_SUCCESS;
      }

    // Execute as a normal call
    // ...
  }
  
}
// Options
internal class Options {

  [Option('c', "connectionString", Required = true, HelpText = Texts.ExplainConnection)]
  public string ConnectionString { get; set; }

  [Option('j', "jobId", Required = true, HelpText = Texts.ExplainJob)]
  public int JobId { get; set; }

  [Usage(ApplicationAlias = "Importer.exe")]
  public static IEnumerable<Example> Examples {
      get => new[] {
          new Example(Texts.ExplainExampleExecution, new Options() {
              ConnectionString="Server=MyServer;Database=MyDatabase",
              JobId = 5
          }),
      };
  }

}

I did a downgrade to version 2.3.0 without any issues. Calling the compiled Program.exe by a command line seems to be working as well. I created that test to ensure my application stops when the version or help is requested only without any additional information.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:19 (4 by maintainers)

github_iconTop GitHub Comments

3reactions
moh-hassancommented, Jan 21, 2019

TL;DR,

I could reproduce the same error in a test project of target framework net472 , but sucess in netcoreapp2.1 using commaline v2.4.3.

This problem is due to the behavior of testhost in Full framework net46.x / net4.7.x and netcore2.x in reading AssemblyAttributes.

This a long story and I have previously posted an issue to vstest project to correct that behavior.

Commandlineparser consider AseemplyAttributes copyright and company shouldn’t be null and raise exception (I think it should be relaxed), which may be null in hosttest and cause troubles with commandlineparser.

To workaround the problem in net472 (compliant with netstandard2) let test classes inherit the following class:

    public class BaseTest
   {
       public BaseTest()  
      {  
	//in case multi target project,use #if because no appdomain in netcore
	#if NET472
        /* Preparing test start */  
        Assembly assembly = Assembly.GetCallingAssembly();  

        AppDomainManager manager = new AppDomainManager();  
        FieldInfo entryAssemblyfield = manager.GetType().GetField("m_entryAssembly", BindingFlags.Instance | BindingFlags.NonPublic);  
        entryAssemblyfield.SetValue(manager, assembly);  

        AppDomain domain = AppDomain.CurrentDomain;  
        FieldInfo domainManagerField = domain.GetType().GetField("_domainManager", BindingFlags.Instance | BindingFlags.NonPublic);  
        domainManagerField.SetValue(domain, manager);  
        /* Preparing test end */  
	#endif
    } 
  }

   //your test class inherit BaseTest
    public class TestProgram: BaseTest
	{
		// Test method (xUnit) which fails and really fail when inheriting the BaseTet class
		[Fact]
		public async Task CallMain_GiveHelpArgument_ExpectSuccess() {
		var result = await Program.Main(new[] { "--help" });
                    int ERROR_SUCCESS = 0;
		Assert.Equal(ERROR_SUCCESS, result);
	  }
	}	

I tested your code in multi-target project in Xunit for net472 and netcoreapp2.1 and both are sucess and NO exception is raised. Run:

   dotnet test

The output in the multi-target test project is:

Test run for F:\github_issues\CommandParser432\CommandParser432\bin\Debug\net472\CommandParser432.dll(.NETFramework,Version=v4.7.2) Microsoft ® Test Execution Command Line Tool Version 15.9.0 Copyright © Microsoft Corporation. All rights reserved.

Starting test execution, please wait…

Total tests: 1. Passed: 1. Failed: 0. Skipped: 0. Test Run Successful. Test execution time: 7.9740 Seconds Test run for F:\github_issues\CommandParser432\CommandParser432\bin\Debug\netcoreapp2.1\CommandParser432.dll(.NETCoreApp,Version=v2.1) Microsoft ® Test Execution Command Line Tool Version 15.9.0 Copyright © Microsoft Corporation. All rights reserved.

Starting test execution, please wait…

Total tests: 1. Passed: 1. Failed: 0. Skipped: 0. Test Run Successful. Test execution time: 5.0017 Seconds

Conclusion:

The xunit test project is working fine when you inherit the TestBase class in net472.

1reaction
moh-hassancommented, Jan 25, 2019

I test your demo and it fail with the error message

Error Message: System.ArgumentNullException : Value cannot be null. Parameter name: element

As a workaround solution, I modified your project by inheriting the class `BaseTest’ that i described in my comment and it pass successfully.

Total tests: 1. Passed: 1. Failed: 0. Skipped: 0. Test Run Successful.

The root error is that the Assemplyattribute copyright and company are null in the hosttest of vstest which is used by NUnit and Xunit, so Commandlineparser raise an exception when execute Assembly.GetEntryAssembly() .

This bug is in net4x only. In netcoreapp2.x test pass successfully. So it’s best to test project in netcoreapp2.x which use the same packages (work only in SDK style project )

IssueDemo-sucess.zip

Read more comments on GitHub >

github_iconTop Results From Across the Web

Value cannot be null in unit test - C# - Stack Overflow
I'm getting this error when I run the unit test: Error Message: System.ArgumentNullException : Value cannot be null. Parameter name: logger ...
Read more >
Favor real dependencies for unit testing
Why internal dependencies are bad. As the above unit test implies, the RestaurantManager relies on an injected IReservationsManager dependency.
Read more >
unittest — Unit testing framework
If you want to pass arguments to test discovery the discover sub-command must be used explicitly. The discover sub-command has the following options:...
Read more >
Unit test reports | GitLab
Unit test reports parsing errors. Introduced in GitLab 13.10. If parsing JUnit report XML results in an error, an indicator is shown next...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found