Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MongoDbFixture fails tests with NullReferenceException #4153

Closed
Xeevis opened this issue May 30, 2020 · 3 comments · Fixed by #4176
Closed

MongoDbFixture fails tests with NullReferenceException #4153

Xeevis opened this issue May 30, 2020 · 3 comments · Fixed by #4176
Assignees
Milestone

Comments

@Xeevis
Copy link
Contributor

Xeevis commented May 30, 2020

I've encountered a curious problem in my project that I'm sadly unable to reproduce with fresh templates, but someone here might have a clue, as I don't want to spend whole day researching this. (Also it might help in case I'm not alone)

Problem lies in MongoDB template test I've implemented without any changes into my existing solution that is already highly modified former template. This line will throw NullReferenceException.

public static readonly string ConnectionString = MongoDbRunner.ConnectionString;

image

It's curious because if I change that public field into property.

//public static readonly string ConnectionString = MongoDbRunner.ConnectionString;
public static string ConnectionString => MongoDbRunner.ConnectionString;

It suddenly works fine ...

image

With fresh template, this change isn't necessary, it just works with field giving me proper headache 😕. Wouldn't property make more sense there though?

ABP 2.8.0
.NET Core SDK 3.1.300

Message: 
    Volo.Abp.AbpInitializationException : An error occurred during ConfigureServices phase of the module MyProject.MongoDB.MyProjectMongoDbTestModule, MyProject.MongoDB.Tests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null. See the inner exception for details.
    ---- System.TypeInitializationException : The type initializer for 'MyProject.MongoDB.MongoDbFixture' threw an exception.
    -------- System.NullReferenceException : Object reference not set to an instance of an object.
  Stack Trace: 
    ModuleLoader.ConfigureServices(List`1 modules, IServiceCollection services)
    ModuleLoader.LoadModules(IServiceCollection services, Type startupModuleType, PlugInSourceList plugInSources)
    AbpApplicationBase.LoadModules(IServiceCollection services, AbpApplicationCreationOptions options)
    AbpApplicationBase.ctor(Type startupModuleType, IServiceCollection services, Action`1 optionsAction)
    AbpApplicationWithExternalServiceProvider.ctor(Type startupModuleType, IServiceCollection services, Action`1 optionsAction)
    AbpApplicationFactory.Create(Type startupModuleType, IServiceCollection services, Action`1 optionsAction)
    AbpApplicationFactory.Create[TStartupModule](IServiceCollection services, Action`1 optionsAction)
    ServiceCollectionApplicationExtensions.AddApplication[TStartupModule](IServiceCollection services, Action`1 optionsAction)
    AbpIntegratedTest`1.ctor()
    MyProjectTestBase`1.ctor()
    MyProjectApplicationTestBase.ctor()
    SampleAppServiceTests.ctor() line 18
    ----- Inner Stack Trace -----
    MyProjectMongoDbTestModule.ConfigureServices(ServiceConfigurationContext context) line 16
    ModuleLoader.ConfigureServices(List`1 modules, IServiceCollection services)
    ----- Inner Stack Trace -----
    MongoDbFixture.cctor() line 8
@maliming
Copy link
Member

maliming commented Jun 1, 2020

It's strange, can you share a project that reproduces the problem?

Or you can adjust the order of static properties,

  1. private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start();
  2. public static readonly string ConnectionString = MongoDbRunner.ConnectionString;

@Xeevis
Copy link
Contributor Author

Xeevis commented Jun 1, 2020

Bingo! It indeed is caused by the order of fields, why didn't I think of that?! The reason why I encountered this is quite simple too, I'm using the popular CodeMaid VS extension that by default sorts member fields by access modifier & alphabetically and never have I encountered this issue before.

This leads me to believe this is highly unusual pattern for class member fields we have here. In my opinion this shouldn't even make it through the compiler. While member field declarations are order agnostic and therefore compiler won't complain if you reference one from another in any order, it's unintuitive code since initialization is still ordered sequence.

Like in this example, one would totally expect either compiler to throw, and if not, then some output from the FooBar. And yet neither will happen ...

private static readonly string FooBar = Foo + Bar;
private static readonly string Foo = "Foo";
private static readonly string Bar = "Bar";
static void Main()
{
    Console.WriteLine("Hello " + FooBar); // Outputs "Hello "
}

@maliming maliming removed the problem label Jun 2, 2020
@maliming
Copy link
Member

maliming commented Jun 2, 2020

I think it is possible to initialize static properties in static constructor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants