Skip to content

Commit

Permalink
improve error message provided by Reqnroll.Microsoft.Extensions.Depen…
Browse files Browse the repository at this point in the history
…dencyInjection plugin when a test execution dependent service is required during [BeforeTestRun]
  • Loading branch information
gasparnagy committed Nov 7, 2024
1 parent fe6308b commit 9c8ba10
Showing 1 changed file with 34 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -157,26 +157,41 @@ private static void RegisterProxyBindings(IObjectContainer objectContainer, ISer
services.AddSingleton(sp => objectContainer.Resolve<IBindingAssemblyLoader>());
services.AddSingleton(sp => objectContainer.Resolve<IUnitTestRuntimeProvider>());

services.AddTransient(sp =>
TResult GetTestThreadDependency<TResult>(IServiceProvider sp, Func<IContextManager, TResult> selector) where TResult: class
{
var container = BindMappings.TryGetValue(sp, out var ctx)
? ctx.ScenarioContext?.ScenarioContainer ??
ctx.FeatureContext?.FeatureContainer ??
ctx.TestThreadContext?.TestThreadContainer ??
objectContainer
: objectContainer;
return container.Resolve<IReqnrollOutputHelper>();
});

services.AddTransient(sp => BindMappings[sp]);
services.AddTransient(sp => BindMappings[sp].TestThreadContext);
services.AddTransient(sp => BindMappings[sp].FeatureContext);
services.AddTransient(sp => BindMappings[sp].ScenarioContext);
services.AddTransient(sp => BindMappings[sp].TestThreadContext.TestThreadContainer.Resolve<ITestRunner>());
services.AddTransient(sp => BindMappings[sp].TestThreadContext.TestThreadContainer.Resolve<ITestExecutionEngine>());
services.AddTransient(sp => BindMappings[sp].TestThreadContext.TestThreadContainer.Resolve<IStepArgumentTypeConverter>());
services.AddTransient(sp => BindMappings[sp].TestThreadContext.TestThreadContainer.Resolve<IStepDefinitionMatchService>());
string GetErrorMessage()
=> $"Unable to access test execution dependent service '{typeof(TResult).FullName}' with the Reqnroll.Microsoft.Extensions.DependencyInjection plugin. This service is only available once test execution has been started and cannot be used in '[BeforeTestRun]' hook.";

if (!BindMappings.TryGetValue(sp, out var contextManager))
{
throw new ReqnrollException(GetErrorMessage());
}

TResult result;
try
{
result = selector(contextManager);
}
catch (Exception ex)
{
throw new ReqnrollException(GetErrorMessage(), ex);
}

if (result == null)
throw new ReqnrollException(GetErrorMessage());

return result;
}

services.AddTransient(sp => GetTestThreadDependency(sp, cm => cm));
services.AddTransient(sp => GetTestThreadDependency(sp, cm => cm.TestThreadContext));
services.AddTransient(sp => GetTestThreadDependency(sp, cm => cm.FeatureContext));
services.AddTransient(sp => GetTestThreadDependency(sp, cm => cm.ScenarioContext));
services.AddTransient(sp => GetTestThreadDependency(sp, cm => cm.TestThreadContext.TestThreadContainer.Resolve<ITestRunner>()));
services.AddTransient(sp => GetTestThreadDependency(sp, cm => cm.TestThreadContext.TestThreadContainer.Resolve<ITestExecutionEngine>()));
services.AddTransient(sp => GetTestThreadDependency(sp, cm => cm.TestThreadContext.TestThreadContainer.Resolve<IStepArgumentTypeConverter>()));
services.AddTransient(sp => GetTestThreadDependency(sp, cm => cm.TestThreadContext.TestThreadContainer.Resolve<IStepDefinitionMatchService>()));
services.AddTransient(sp => GetTestThreadDependency(sp, cm => cm.TestThreadContext.TestThreadContainer.Resolve<IReqnrollOutputHelper>()));
}

private class RootServiceProviderContainer
Expand Down

0 comments on commit 9c8ba10

Please sign in to comment.