Changing the value of a private static readonly field of a static class using reflection, doesn't reliably work. I have the following methods that use reflection to set values to variables or retrieve a variable (static variables) Code (CSharp): //Provide the names of the variables and values for them, and this method sets them. public static void InitMembers (Type type, string[] names, object[] values) { for (int i = 0; i < names.Length; i++) { type.GetField(names[i], BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static).SetValue(null, values[i]); } } //Can be used for static classes public static object GetMember (Type type, string attrName) { return type.GetField(attrName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static).GetValue(null); } I have a test static class: Code (CSharp): static class TestStatic { private static readonly string[] strs1 = new string[] {"11","22","33","44"}; public static string[] getStrs() { return strs1; } public static void printArray(string prefix, string[] arr) { string s = prefix+"length: "+arr.Length+"{"+arr[0]+"}"; Debug.Log(s); } } And I have this test that changes the value of strs to a new string[] with one element only and then asserts that the strs value that we are getting from the public method of the class is the same as the one we are getting with reflection: Code (CSharp): [Test] public void some_test(){ TestingUtils.InitMembers(typeof(TestStatic), new string[]{"strs1"}, new object[]{new string[]{"eh"}}); Assert.AreEqual(TestStatic.getStrs(), TestingUtils.GetMember(typeof(TestStatic), "strs1")); } I run the tests: 1 time : passes 2 time : passes 3+ time : oh boy... Basically after the second time, each time it fails in a different spectacular way, some examples: Expected: System.Array+InternalEnumerator`1[[UnityEditor.Scripting.ScriptCompilation.CustomScriptAssemblyPlatform, UnityEditor.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]] But was: < "eh" > Expected: System.Collections.Generic.HashSet`1+Enumerator[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] But was: < "eh" > Expected: <UnityEngine.GUILayoutOption> But was: < "eh" > Yeah you get the point. Looks like a bufferoverflow of some sort. Funny thing is that if i remove the readonly keyword from strs then it works! Also another thing, If you change the value of a static field of a class in a (EditMode) test, then it will keep this value if you rerun the test. But if you modify the code in any way, even blank line, to make it recompile, the value gets reset. Not cool. How can this be happening?
You're not changing the actual code, so it's not saving your change anywhere. When the code is recompiled, the original value is restored. This is to be expected. As to the original issue, looks like this has something to do with the Unity runtime. Another user reported similar symptoms years ago: https://stackoverflow.com/a/23615644 I think the short answer is don't reflect readonly fields.
Sorry I am not sure I am getting it. Yes I am not changing the actual code that's the point, I only modify the value at runtime, how can it still have the same changed value when i rerun the test?
Ah, I misunderstood your frustration -- the changed value will stay between tests because the editor environment & all the objects loaded in it, including static classes, are persistent until a domain reload occurs. This happens on recompile, due to code changes, or on entering play mode if you have domain reloading enabled. Executing a test doesn't reload the domain, so static state will persist. In your case, you would need to make use of setup/teardown capabilities to make sure that what you're testing is in the correct state when you run your tests. In this instance, you might reset the value of your static variable.