Reputation: 1335
We have recently added Azure App Configuration into our Azure Functions, and we now want the Startup code for the App Configuration to be triggered via the tests.
Our function startup code looks like this -
public override void Configure(IFunctionsHostBuilder builder)
{
config = Utils.LoadConfig();
StartupHelper.AddCommonIoCDependencies(builder);
}
public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder)
{
//How do we trigger this method when testing???
StartupHelper.AddAzureAppConfiguration(builder);
}
The initial configure method is triggered when running tests by using the following -
private MyFunction_sut;
[SetUp]
public void Setup()
{
var funcStartup = new Startup();
var host = new HostBuilder()
.ConfigureWebJobs(funcStartup.Configure)
.Build();
_sut = new MyFunction(...);
}
This works for triggering the Congfigure method. And despite the HostBuilder having options for ConfigureAppConfiguration, I can't figure out how to get this working. I feel there should be a quick and easy way with what I've put below.
var host = new HostBuilder()
.ConfigureWebJobs(funcStartup.Configure)
.ConfigureAppConfiguration(x => {
//What do I put here to call trigger the ConfigureAppConfiguration method at startup?
//Or is it possible to call my helper "AddAzureAppConfiguration" method that is in a static class?
})
.Build();
If there's a different way to test Azure Functions to add in Azure App Configuration that doesn't involve HosatBuilder then I'd love to hear other people's approaches. I really can't see much for this when googling online, so I feel like I'm missing something.
Any advice is appreciated!
Upvotes: 2
Views: 2800
Reputation: 126
There is a ConfigureWebJobs
extension method overload you can use to do this:
public static IHostBuilder ConfigureWebJobs(this IHostBuilder builder,
Action<HostBuilderContext,
IWebJobsBuilder> configure,
Action<JobHostOptions> configureOptions,
Action<HostBuilderContext, IWebJobsConfigurationBuilder> configureAppConfiguration)
You can trigger your ConfigureAppConfiguration
by calling UseWebJobsConfigurationStartup
on the configureAppConfiguration
parameter like this:
var webJobsBuilderContext = new WebJobsBuilderContext();
var host = new HostBuilder()
.ConfigureWebJobs((context, builder) =>
{
builder.UseWebJobsStartup(typeof(TestStartup), webJobsBuilderContext, NullLoggerFactory.Instance);
}, _ => { }, (context, builder) =>
{
builder.UseWebJobsConfigurationStartup<TestStartup>(webJobsBuilderContext);
})
.Build();
Upvotes: 1
Reputation: 2838
I needed to do something similar. Unfortunately the implementation of IFunctionsConfigurationBuilder
, which is needed to accomplish this, is marked internal
so I had to duplicate the implementation myself. Thankfully it is simple.
// https://github.com/Azure/azure-functions-dotnet-extensions/blob/main/src/Extensions/DependencyInjection/FunctionsConfigurationBuilder.cs
internal class FunctionsConfigurationBuilder : IFunctionsConfigurationBuilder
{
public FunctionsConfigurationBuilder(IConfigurationBuilder configurationBuilder, WebJobsBuilderContext webJobsBuilderContext)
{
ConfigurationBuilder = configurationBuilder ?? throw new ArgumentNullException(nameof(configurationBuilder));
Context = new DefaultFunctionsHostBuilderContext(webJobsBuilderContext);
}
public IConfigurationBuilder ConfigurationBuilder { get; }
public FunctionsHostBuilderContext Context { get; }
}
// https://github.com/Azure/azure-functions-dotnet-extensions/blob/main/src/Extensions/DependencyInjection/DefaultFunctionsHostBuilderContext.cs
internal class DefaultFunctionsHostBuilderContext : FunctionsHostBuilderContext
{
public DefaultFunctionsHostBuilderContext(WebJobsBuilderContext webJobsBuilderContext)
: base(webJobsBuilderContext)
{
}
}
This allows me to setup my testing like this:
public TestHost()
{
var webJobsBuilderContext = new WebJobsBuilderContext();
var startup = new TestStartup();
var host = new HostBuilder()
.ConfigureAppConfiguration((context, builder) =>
startup.ConfigureAppConfiguration(new FunctionsConfigurationBuilder(builder, webJobsBuilderContext))
)
.ConfigureWebJobs((context, builder) =>
{
webJobsBuilderContext.Configuration = context.Configuration;
startup.Configure(webJobsBuilderContext, builder);
})
.Build();
ServiceProvider = host.Services;
}
public IServiceProvider ServiceProvider { get; }
And the Startup
for my tests looks like:
private class TestStartup : Startup
{
public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder)
{
// Do anything else you need to here
base.ConfigureAppConfiguration(builder);
}
public void Configure(WebJobsBuilderContext context, IWebJobsBuilder builder)
{
// Do anything else you need to here
base.Configure(context, builder);
}
}
That's pretty much it. Let me know if further details are needed. It's not straightforward unfortunately.
Upvotes: 6