mamidon
mamidon

Reputation: 895

CloudConfigurationManager.GetSetting Returns Null in Unit Tests

So I've written an Azure worker role and some unit tests to verify that it works as expected. The problem is that CloudConfigurationManager.GetSetting always returns null.

The following WorkerRole method is called before any unit test is run:

 public override bool OnStart()
 {
    string connectionString = CloudConfigurationManager.GetSetting("StorageConnectionString");

    var account = CloudStorageAccount.Parse(connectionString);
    ...
 }

I used Visual Studio's settings gui to actually set the connection string properties (different ones for local and cloud deployments) so I know the cscfg files should be valid. Here's what the local ServerAgent settings look like:

<Role name="ServerAgent">
<Instances count="1" />
<ConfigurationSettings>
  <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="UseDevelopmentStorage=true" />
  <Setting name="StorageConnectionString" value="SUPER SEKRET" />
</ConfigurationSettings>

So I guess the question is, how does CloudConfigurationManager find the correct cscfg file? The unit test project takes a reference to the ServerAgent project, but the ServerAgent project doesn't take any sort of reference to the CloudService project.

Solution layout

Upvotes: 4

Views: 3132

Answers (2)

Ogail
Ogail

Reputation: 177

You need to have the value in *.cscfg and *.csdef as well to expose the value:

<ConfigurationSettings>
      <Setting name="<setting-name>" />
</ConfigurationSettings>

http://msdn.microsoft.com/en-us/library/gg557553.aspx

Upvotes: -2

Mark Seemann
Mark Seemann

Reputation: 233125

When a test runner executes tests, it typically runs the tests in either of

  • a new AppDomain
  • a new process

It depends a little on the test runner, but using a new AppDomain seems to be the most common approach these days.

Each new process or AppDomain has its own configuration settings, which are not going to be your .cscfg files. Typically, by convention, most test runners will pick up configuration settings from the unit test project's app.config file, so try putting the configuration settings in ServerAgent.Tests.app.config.

That said, I'd recommend that you refactor your System Under Test so that it doesn't depend on configuration settings, because configuration settings are very difficult to vary during testing.

Imagine that you'd like to test the behaviour of your system for different configuration values. If you use the configuration files, you can't easily do that.

While I realize that an Azure Worker Role requires that there's an OnStart method with a particular signature, implement it as a Humble Method:

public override bool OnStart()
{
    string connectionString =
        CloudConfigurationManager.GetSetting("StorageConnectionString");

    return OnStartImpl(connectionString);
}

public bool OnStartImpl(string connectionString)
{
    // Put all implementation code here
}

Then test OnStartImpl instead.

BTW, if you're running automated tests that connect to real cloud services, they're not unit tests, but something else. While I don't know your motivation for writing tests, consider writing most of your tests so that they do not depend on extraneous services.

Upvotes: 4

Related Questions