0

I have an app.config which is working fine.

But I also have a tool for automated testing, that runs some tests in environment without any file access. So I have to read a config file from string (or memory stream), but without mapping it physically because there is no access to file system from this automatic testing process.

In real life, of course, config file is stored somewhere, but for automated testing purposes I need some workaround to read a config file from string stored in memory. Is it even possible? I googled a lot, but the only thing I found is Save it as temp file and then read, but it's not my case.

Alex Zhukovskiy
  • 9,565
  • 11
  • 75
  • 151
  • might consider some kind of database as a storage, it won`t be a good solution though... – Vladimir Apr 19 '16 at 11:47
  • what are the possible inputs for your tool?! Can it read environment variables? is it a product or did you create it? – Gubr Apr 19 '16 at 11:49
  • It can read everything, just user doesn't have permissions or write on disk. I'm looking for MMF for now, but still not sure if it work. – Alex Zhukovskiy Apr 19 '16 at 11:50
  • 2 questions.... First - How your code is going to retieve the "config" values? Is your test tool deployment environment allows deliver newer version of test tool with some text files? – Yaugen Vlasau Apr 19 '16 at 11:53
  • Can you not make a parametric string? I can Imagine that the whole config file will not Change, but some values in it. You could make them parametric. – Abhishek Kumar Apr 19 '16 at 11:55
  • @YaugenVlasau text is stored as embedded resource in `resx` file. But I didn't really understand your second question. – Alex Zhukovskiy Apr 19 '16 at 12:12
  • 1
    @AbhishekKumar firsly, I'm writing a test that checks that config is deserialized properly (all keys are has right capitalization and so on), so it's impossible. And second, even If i needed some values, config is currently read-only with initialization at app start. It's not a good practice to make some props non-readonly for test purposes only. – Alex Zhukovskiy Apr 19 '16 at 12:14

3 Answers3

1

Without the configuration file you'll have the default settings. You may override the default values:

Properties.Settings.Default["PropertyName"] = NewPropertyValue";

(Set the correct access modifier on your Settings class and use the correct namespace if it is in a library)

Sergey L
  • 1,402
  • 1
  • 9
  • 11
1

Avoid a direct dependency from your class on app.config or any other file. Your class doesn't need app.config or Properties.Settings. It needs the values contained in the those files..

If you create a workaround for testing purposes then you're testing a different version of your class. That's the inherent problem - direct dependency on these files isn't testable. It doesn't mean that they're bad in some way or that we shouldn't use them, only that the class that requires the values should not read them from the file.

An ideal solution is constructor injection, a form of dependency injection. Provide the value to the class in its constructor and store it as a field. That way when the class is created it always has the values it needs.

At runtime you can use a dependency injection container - here's a walkthrough on setting one up for WCF. You're likely in a different project type, but the concepts still apply.

But for testing, it's as easy as creating a class and passing whatever value you want to use into the constructor. It's impossible to test with different values when the class reads from settings but it's easy using constructor injection.

Scott Hannen
  • 27,588
  • 3
  • 45
  • 62
  • You're right. It not a unit test, it's an integration test so I need proper envorinment settings. Thus, I will ask for a file access becuase it's impossible to test proper file parsing without file itself. It's sad that `ConfigurationManager` do not provide a proper API with stream, but I don't want to write a wrapper around it while it could handle everything about serializarion itself. Yes, it's not possible to mock it, but my test purposes was very this task: check, that everydata written in XML is properly mapped on domain objects. – Alex Zhukovskiy Apr 19 '16 at 13:50
0

As first option I would go for Settings file in your case. Even your user won't be ablle to access settings file content. Then it will return a default value for a particualr property.

You can try creaty a silly console app

static void Main(string[] args)
{
    Console.WriteLine(Settings.Default.MyProperty);
    Console.ReadLine();
}

were you set the your value for MyProperty on the Settings Tab of you Project Properties. Then you can build your solution, open the binaries folder and delete your exe.config file and you will see that the app will be use default values.

As second option you can use command line arguments. could also be an option for you. (Here the article about some tricky case for command line arguments Backslash and quote in command line arguments )

Third option could be placing your file at c:\users\your app user \AppData\Roaming\YourAppName folder. here you should be granted for file access even for restricted user

For education reason I would also reccomend to look at this article: https://msdn.microsoft.com/query/dev11.query?appId=Dev11IDEF1&l=EN-US&k=k(ApplicationSettingsOverview);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5)&rd=true Maybe you find the "Load Web Settings" option nice.

Another palce for investigation could be

Community
  • 1
  • 1
Yaugen Vlasau
  • 2,148
  • 1
  • 17
  • 38