nunit / nunit-console

NUnit Console runner and test engine
MIT License
211 stars 149 forks source link

ComponentNotRegisteredException when executing test cases using NUnit Console 3.16.3 (Release) #1391

Open marossi7 opened 4 months ago

marossi7 commented 4 months ago

We recently lifted .NET Framework project to .NET 7. All went without major complications, but we encountered an issue when we were trying to execute test cases from a .NET 7 test library using NUnit Console 3.16.3 (Release). The interesting fact is that the tests are running fine when ran from Visual Studio, but as longs as we run them from the console runner the following error is encountered.

1) Error : TestRunnerModule.Integration.Tests.ConnectionTestRunnerIntegrationTests.TestRunnerPortTestUpdate_UpdatesWizardData(READyCollector)
Autofac.Core.Registration.ComponentNotRegisteredException : The requested service 'MediatorModule.IMediator' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.

See https://autofac.rtfd.io/help/service-not-registered for more info.
   at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable`1 parameters)
   at Autofac.ResolutionExtensions.Resolve(IComponentContext context, Type serviceType, IEnumerable`1 parameters)
   at Autofac.ResolutionExtensions.Resolve[TService](IComponentContext context, IEnumerable`1 parameters)
   at Autofac.ResolutionExtensions.Resolve[TService](IComponentContext context)
   at TestRunnerModule.Integration.Tests.ConnectionTestRunnerIntegrationTests.TestRunnerPortTestUpdate_UpdatesWizardData(DeviceType deviceType) in C:\Users\MHR\source\concentratortool\Tests\DotNet\IntegrationTests\TestRunnerModule.Integration.Tests\ConnectionTestRunnerIntegrationTests.cs:line 241
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)

In the test case we use IoC (Autofac 7.0.1) and we are loading assembly modules using Module Scanning. Module scanning is performed with the RegisterAssemblyModules() registration method, which does exactly what its name suggests.

var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
List<Assembly> allAssemblies = new List<Assembly>();
foreach (string dll in Directory.GetFiles(path, "*MediatorModule.dll"))
{
     allAssemblies.Add(Assembly.LoadFrom(dll));
}
foreach (string dll in Directory.GetFiles(path, "*WizardDataModule.dll"))
{
     allAssemblies.Add(Assembly.LoadFrom(dll));
}

 allAssemblies.Add(Assembly.GetExecutingAssembly());

var builder = new ContainerBuilder();
builder.RegisterAssemblyModules(allAssemblies.ToArray());
Container = builder.Build();

When trying to resolve registered assembly / ies (see below) the exception mentioned in the beginning is thrown.

using (var scope = Container.BeginLifetimeScope())
{
    var mediator = scope.Resolve<IMediator>();
    var wizardDataModule = scope.Resolve<IWizardDataModule>();
...

I am not sure this is the correct place to report this, but the whole thing works fine in the Visual Studio environment, but not through the NUnit Console 3.16.3 (Release).

OsirisTerje commented 4 months ago

Can you please check the 3.17 version.

The 3.16 series are abandoned, and 3.17 is a continuation of 3.15, which is what is used in the adapter, and thus dotnet and Visual Studio.

marossi7 commented 4 months ago

Updated to 3.17. It provides me with the same results.

OsirisTerje commented 4 months ago

Ok, that means the error is in the console code, not in the engine code.

Or, that you need to add something to the Autofac registration, that is, scanning is not enough. Perhaps also raise a question with the Autofac guys.

Suggest you also upload a small repro that reproduce this error.

And, do you really need to use the console, can you use dotnet test instead ?

marossi7 commented 4 months ago

Raised the question with the Autofac guys, but they dismissed it saying that it is most likely a problem with environment, which is quite fair argument I guess.

Our existing pipeline has been using console runner and I was just hoping it would still work onwards. However, thanks for the tip - I just tested it with dotnet test and it works like charm. We will switch to this strategy instead.

Do you want me to set up small repo to preproduce this issue that could help you trace what could be wrong with it ?

OsirisTerje commented 4 months ago

Good to hear that dotnet test works for you.

Do you want me to set up small repo to preproduce this issue that could help you trace what could be wrong with it ?

It would be awesome, then we having something to check when we get to this.

CharliePoole commented 1 month ago

@marossi7 Any more info on this? If not I will close it.

BTW, @OsirisTerje commented that the problem is probably not with the engine, because the vs adapter uses the engine. That's not 100% certain as the adapter uses only a subset of the engine's features. In particular, the adapter doesn't create processes, since VS has already created the process used by the tests.