Magic numbers. Reading from config file the same as global space? Bad for unit testing?
Consider the following class:
class Something : ISomething {
public void DoesSomething(int x) {
if (x == 0) {
x = 1;
}
}
}
I want to remove the magic number of course - my unit tests are passing, etc., but I want to refactor the horrible magic number.
I am using C #, but I think this problem is pretty general. Reading from a configuration file (xml file) is done with the following:
ConfigurationManager.AppSettings["MyOldMagicNumber"]...
Which of course would be crap to test. I could easily make a private function in this class that is marked virtual. Its purpose is to encapsulate this code above. This would allow me to access in my unit tests to override and wire my own value.
My question is -
Is it really bad that I am doing? See Chapter.
Edit:
This is for the game - so it is more likely during development that values will change frequently and rebuilding will be difficult. I should have mentioned that the above code is generic, I made the question as simple as possible. A bit of context though - it's '0' - the boundaries of the game area.
Thanks in advance.
a source to share
Why don't you create an interface for this like
public interface IApplicationSettings {
int MyOldMagicNumber { get; }
}
They then have two implementations of this: one for production that reads from a config file and one fake for unit tests.
public class ApplicationSettings : IApplicationSettings {
public int MyOldMagicNumber {
get { return ConfigurationManager.AppSettings["MyOldMagicNumber"]; }
}
}
public class FakeApplicationSettings : IApplicationSettings {
public int MyOldMagicNumber {
get { return 87; /*Or whatever you want :) */ }
}
}
a source to share
Do you really need to change these values without recompiling the program? If not, I think you should not put it in your config file, otherwise you end up programming in xml;)
Using constants is useful for readability in this case:
class Something : ISomething {
public const int Zero = 0;
public const int One = 1;
public void DoesSomething(int x) {
if (x == Zero) {
x = One;
}
}
}
a source to share
I would definitely put it in a config file if you are making a game. This is because you may (want) to try a different set of values. Putting it in the config file means that you can change files and try new numbers without changing the "engine". You can even define the properties / values of each game criterion in the config, and that's okay!
a source to share