C# How can I force Localization Culture to en-US for tests project
Asked Answered
T

7

59

How to specify concrente Localization Culture for tests project in C# in VS2008? I'm building Asp .Net MVC app that has nonstandard culture specified in web.config but how to set the same culture for unit tests for that project?

Threescore answered 15/2, 2011 at 8:14 Comment(0)
G
78

You may set

Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); 

in method that is marked as "test initializer" in your unit testing framework.

Geometric answered 15/2, 2011 at 8:25 Comment(7)
you can set this just before the method you are calling that you want to have the specific culture, you don't need to do it in the test setup. and you may not want to if you just need to set it for one test.Freeholder
I'm really wary about challenging such an upvoted answer, but I believe it should be Thread.CurrentThread.CurrentUICulture and not CurrentCulture. The Intellisense for CurrentUICulture itself says Gets or sets the current culture used by the Resource Manager to look up culture-specific resources at run time. My tests fail when using testing against an "fr-FR" culture resource using CurrentCulture, but pass when using CurrentUICulture.Batter
web.config allows to specify both cultures via <globalization uiCulture="es" culture="es-MX" />. Depending on what attribute you use in the real application you may set the appropriate property for unit test. The original questions asks about culture, not uiCulture but this is subject for interpretation.Geometric
I've tested this on VS2015 and it's definitely CultureInfo @NeilMossUnlucky
@quango My concern wasn't the CultureInfo reference - I was questioning if it should be CurrentUICulture instead of CurrentCultureBatter
@NeilMoss As you pointed out, CurrentUICulture sets the culture used when loading resources. CurrentCulture is used for things like converting DateTime and Decimal values to strings, so chances are, you want both. In your case, it looks like you're using it to test that the correct localized resource strings are returned. In the OP's case, they are probably using it to test how Decimal and DateTime values are displayed. (They definitely should have specified this in their question.)Redeeming
I'm using MSTEST. What if you want to test multiple cultures, how would I set that up? I don't want to duplicate tests just to run it in a different culture and I don't want to manually change culture settings. It'd be nice to be fully automated.Avon
T
29

If you're using xUnit, you can add the UseCultureAttribute to your project, as defined here:

https://github.com/xunit/samples.xunit/blob/master/UseCulture/UseCultureAttribute.cs

To use it:

[Fact]
[UseCulture("en-US")]
public void MyTest()
{
    // ...
}
Twigg answered 18/3, 2017 at 22:18 Comment(3)
Was a bit confused by the comment, but when you mean add UseCultureAttribute you mean to copy the whole file into your project? Since it seems it is not included in the core nuget github.com/xunit/xunit/issues/290 and will never be.Jarlath
@Jarlath yes, you need to copy that attribute's source code. It's an example of BeforeAfterTestAttribute which is part of xUnit.Twigg
For Nuint, its SetCulturePageboy
R
13

If you want to specify the CultureInfo for your entire Test Suite without having to add it in the TestInitializer of every TestClass, you can use the AssemblyInitializeAttribute.

Inside a Test Class (a class decorated with the attribute [TestClass]), add a static method that sets DefaultThreadCurrentCulture and DefaultThreadCurrentUICulture, and then decorate that method with [AssemblyInitialize].

This method will then be run once when your test suite starts up, before any TestMethods are run. (Note: you may only have one such method decorated with this attribute in your test suite.)

Here is an example of using a dedicated Test Class that just sets up the culture, but you can put it in any Test Class:

[TestClass]
public static class InitializeCulture
{
    [AssemblyInitialize]
    public static void SetEnglishCultureOnAllUnitTest(TestContext context)
    {
        Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
        Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
    }
}
Redeeming answered 30/8, 2017 at 13:38 Comment(1)
Good approach, but be careful when having multiple threads. The assembly init occurs once, and other threads may be initialized differently. Using the nunit or xUnit attributes for culture is more resilient and self documenting (and can be applied to an entire class).Alvey
N
8

For nUnit 3, you can use the attributes [SetCulture("en-US")] and [SetUICulture("en-US")]. This will force the culture for this single test.

Neckline answered 26/2, 2019 at 13:55 Comment(1)
And putting this before your test class will apply to all your testQuadrillion
R
3
System.Globalization.CultureInfo ci = new System.Globalization.CultureInfo("en-US");
System.Threading.Thread.CurrentThread.CurrentCulture = ci;
Reavis answered 15/2, 2011 at 11:8 Comment(0)
G
2

The following method worked for me:

[TestClass]
public class MyTestClass
{ 
   [TestInitialize]
   public void InitializeTestClass()
   {
      Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
      Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
   }

   .......... [other unit tests]
}
Grapery answered 15/3, 2021 at 13:30 Comment(0)
T
0

There isn't a setting similar to the one in web.config that will work in your case.

You could try setting it for each thread as suggested by the other answers here.

Alternatively if you are using resources created in VS.NET, the code generation creates a static property on the Resource class called 'Culture'. You could set that in your unit test's Suite startup method. That will apply to all the tests that you run.

Topsail answered 1/4, 2011 at 22:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.