How to Mock Configurationmanager.Appsettings with Moq

How to mock ConfigurationManager.AppSettings with moq

I believe one standard approach to this is to use a facade pattern to wrap the configuration manager and then you have something loosely coupled that you have control over.

So you would wrap the ConfigurationManager. Something like:

public class Configuration: IConfiguration
{
public string User
{
get
{
return ConfigurationManager.AppSettings["User"];
}
}
}

(You can just extract an interface from your configuration class and then use that interface everywhere in your code)
Then you just mock the IConfiguration. You might be able to implement the facade itself in a few different ways. Above I chose just to wrap the individual properties. You also obtain the side benefit of having strongly typed information to work with rather than weakly typed hash arrays.

Mocking ConfigurationManager.AppSettings with JustMock

source: http://www.telerik.com/community/forums/justmock/general-discussions/problems-mocking-the-configurationmanager-appsettings.aspx

Official response is, this appears to be an issue with MSTest only.

How to mock config file for unit test

You cannot Mock values of a and b as your code is tightly coupled with app.config file. You can create an interface. Refactor code like below to inject an interface to you constructor and then mock it,

 public class ABC
{
private int a;
private int b;
public ABC(IConfig config)
{
a = config.a;
b = config.b;
}

public int Method1(IDictionary<string, string> dict)
{
int d = a + b / 2;

return d;
}
}

public interface IConfig
{
int a { get; }
int b { get; }
}
public class Config : IConfig
{
public int a => Convert.ToInt32(ConfigurationManager.AppSettings["GetValue"]);
public int b => Convert.ToInt32(ConfigurationManager.AppSettings["GetValue1"]);
}

And in you test class Mock and inject IConfig like below,

Mock<IConfig> _mockConfig = new Mock<IConfig>();

_mockConfig.Setup(m => m.a).Returns(1);
_mockConfig.Setup(m => m.b).Returns(2);

ABC abc = new ABC(_mockConfig.Object);

Now your code is decoupled with app.config and you will get mock values of a and b while running unit test.

ConfigurationManager.AppSettings Returns Null In Unit Test Project

You mentioned settings in the project properties. See if you can access the setting this way:

string test = Properties.Settings.Default.Bing_Key;

You may need to get the executing assembly of where the project settings file is defined, but try this first.

EDIT

When using Visual Studio's project settings file, it adds stuff to your app.config and creates the app.config if it is not present. ConfigurationManager CAN'T touch these settings! You can only get to these specific generated project.settings file from using the above static method. If you want to use ConfigurationManager, you will need to hand write your app.config. Add your settings to it like so:

<appSettings>
<add key="bing_api" value="whatever"/>
</appSettings>

How to mock IConfiguration.GetValue

You can use an actual Configuration instance with in-memory data.

//Arrange
var inMemorySettings = new Dictionary<string, string> {
{"TopLevelKey", "TopLevelValue"},
{"SectionName:SomeKey", "SectionValue"},
//...populate as needed for the test
};

IConfiguration configuration = new ConfigurationBuilder()
.AddInMemoryCollection(inMemorySettings)
.Build();

//...

Now it is a matter of using the configuration as desired to exercise the test

//...

string value = configuration.GetValue<string>("TopLevelKey");

string sectionValue = configuration.GetSection("SectionName").GetValue<string>("SomeKey");

//...

Reference: Memory Configuration Provider

Mock settings in Web.conf with moq

You are better off if you abstract the config file reading, and inject this abstraction into your class, instead of using directly ConfigurationManager. Then for your tests you can mock the abstraction.

Create a IConfigurationReader interface:

public interface IConfigurationReader
{
string GetConfigSetting(string settingName);
}

The real implementation will use ConfigurationManager, but for tests you can mock IConfigurationReader.

It may seem overkill, but it's one time work which can be reused all over your application(s). The added benefit is, that if some day you decide to read configuration settings from somewhere else, you just change the implementation, w/o touching your consumers.



Related Topics



Leave a reply



Submit