0

I have written the following to stub a Singleton for the purpose of unit testing.

 public static class LocalisationSetter
    {
        [ThreadStatic]
        private static CultureInfo _cultureInfo;

        public static void Set(CultureInfo cultureInfo)
        {
            _cultureInfo = cultureInfo;

            Localisation.Current.Culture = _cultureInfo; // Setting The singleton.
        }
    }

In my test I do something like below:

LocalisationSetter.Set(new CultureInfo("fr-FR"));

The above method just seems little "dirty"...

Just wondered if there is potentially a better way. I need to make sure the changes to "Localisation" is only visible to the thread.

3
  • Correct me if I'm wrong, but if Localisation.Current is not ThreadStatic also then your Setter class is pointless. Even if it is, the class doesn't do anything that you couldn't do straight from the test. Commented Mar 10, 2014 at 22:24
  • 1
    Can you clarify if there's something about this that is specific to unit testing? Commented Mar 10, 2014 at 22:30
  • Is there a particular reason you don't just set the thread's current culture? That is Thread.CurrentCulture = cultureInfo; Also Thread.CurrentUICulture. Commented Mar 11, 2014 at 2:54

1 Answer 1

3

Having a class that is a "Setter" is a fairly peculiar pattern. As DStanley commented, the above will not work as expected without Making Localization.Current thread-static, too:

public class Localization{

   [ThreadStatic]
   private static Localization _current;

   public static Current {
     get { _current = _current ?? new Localization(); return _current }
     set { _current = value; }
   }
}

That being said, this is generally a very peculiar pattern, as this is effectively creating "global" variables, which generally makes unit testing, and software maintenance more complicated.

(The above code creates ephemeral state that could change at any time, impacting the behavior of your code).

Consider using dependency injection, or at a minimum, organizing these "global" variables into a few aggregate objects so that the fact that you do have these context objects around is easier to track.

Sign up to request clarification or add additional context in comments.

2 Comments

I thought if the "global" refers to a thread static instance then each thread will get its own copy. This way each test can run in isolation. Thanks!
@msuhash, It's true that ThreadStatic will isolate this per thread, but the point of my answer was that you're creating shared state and not passing it via normal conventions (i.e. method calls/passing objects). This is probably a code smell, and should be avoided.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.