I am working on integration tests of .NET Core application and want to use some test configuration. My configuration is a POCO class that is configured via appsettings.json
and then consumed via IOptions<T>
. In my tests I'd like to use an instance of that class.
Here is the code:
var mySettings = GetTestSettings(); // factory method returning POCO class
var configurationBuilder = new ConfigurationBuilder();
// I am looking for something like
configurationBuilder.AddInMemoryObject("Settings", mySettings);
// does not work, result is just string
configurationBuilder.AddInMemoryCollection("Settings",
JsonConvert.SerializeObject(mySettings));
// requires filename
configurationBuilder.AddJsonFile("filename.json");
What is the easiest way to feed POCO to configuration?
The IConfiguration is an interface for . Net Core 2.0. The IConfiguration interface need to be injected as dependency in the Controller and then later used throughout the Controller. The IConfiguration interface is used to read Settings and Connection Strings from AppSettings. json file.
The launchSettings. json file is used to store the configuration information, which describes how to start the ASP.NET Core application, using Visual Studio. The file is used only during the development of the application using Visual Studio. It contains only those settings that required to run the application.
AddInMemoryCollection
takes a collection of KeyValuePair
where a key is setting key and value is its value. This call from the question
configurationBuilder.AddInMemoryCollection("Settings", JsonConvert.SerializeObject(mySettings));
actually passes "Settings" as a key and whole JSON as one setting value, which expectedly does not work.
But the overall approach is correct, you should use AddInMemoryCollection
extension call. In collection passed to this call, setting keys are full paths within configuration, delimited by a colon. Say if you have following settings POCO:
public class SomeSettings
{
public string SomeKey1 { get; set; }
public int SomeKey2 { get; set; }
}
and it's loaded from following JSON
{
"SomeSettings": {
"SomeKey1": "SomeData",
"SomeKey2": 123
}
}
the keys would be SomeSettings:SomeKey1
and SomeSettings:SomeKey2
.
You could then add such configuration with following AddInMemoryCollection
call:
configurationBuilder.AddInMemoryCollection(new Dictionary<string, string>
{
{ "SomeSettings:SomeKey1", "SomeData" },
{ "SomeSettings:SomeKey2", 123 },
});
Now, if you want to add settings POCO with one call, you could write simple extension method that will enumerate setting class properties using reflection and return collection of key-value pairs for properties names and values.
Here is a sample:
public static class ObjectExtensions
{
public static IEnumerable<KeyValuePair<string, string>> ToKeyValuePairs(this Object settings, string settingsRoot)
{
foreach (var property in settings.GetType().GetProperties())
{
yield return new KeyValuePair<string, string>($"{settingsRoot}:{property.Name}", property.GetValue(settings).ToString());
}
}
}
public static class ConfigurationBuilderExtensions
{
public static void AddInMemoryObject(this ConfigurationBuilder configurationBuilder, object settings, string settingsRoot)
{
configurationBuilder.AddInMemoryCollection(settings.ToKeyValuePairs(settingsRoot));
}
}
In the test:
var configurationBuilder = new ConfigurationBuilder();
var mySettings = GetTestSettings();
configurationBuilder.AddInMemoryObject(mySettings, "Settings");
Such simple ObjectExtensions.ToKeyValuePairs
extension method will work for plain POCO like SomeSettings
above. However it will not work if some of the properties are also objects like here:
public class InnerSettings
{
public string SomeKey { get; set; }
}
public class OuterSettings
{
public InnerSettings InnerSettings { get; set; }
}
However I believe you got an idea and could make required adjustments if required.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With