I have come across Unit testing project where in the messages,labels are hardcoded in English and while implementing for other countries have failed unit test cases.
This led me to write this blog post of Internationalization (I18N) Unit Testing.
The problem is strings are hardcoded in Unit testing and while different county and respective language is tested, It’s not an effective way to test.
Let’s create a Solution with class library and Unit test. Completed solution structure is as shown in below Figure 1
Fig 1
Lets add two Resource file to Core Project and Name it Messages.
In C#, Default County is US and language is en (English), to add specific resource file the format to use is
<NameOfFile>.language–Country.resx
example for France, French would be Message.fr-FR.resx
I usually like to put all constant in a separate class file, you can create a new class and add. Complete code for constant file as below
namespace TDD.Core
{
public class ApplicationConstant
{
public const string WELCOME_KEY = "Welcome";
}
}
Add class name as you wish and complete code snippet is as below. Code to read from Resource file and return the text based on key.
using TDD.Core.Resources;
namespace TDD.Core
{
public class ResourceTest
{
public string GetResources()
{
return Message.ResourceManager.GetString(ApplicationConstant.WELCOME_KEY);
}
}
}
In Test project add new file and write 2 test cases for US and FR countries Unit testing.
One important line for explanation is
Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr-FR");
This would make the current UI Culture testing thread to use the Language French and Country France. You see there is no hardcoding of message is any specific language, message are taken from Resource file itself.
Complete code is as shown below
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Globalization;
using System.Threading;
using TDD.Core;
using TDD.Core.Resources;
namespace TDD.Test
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void Test_French_France_Culture()
{
//Arrange
Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr-FR");
ResourceTest classUnderTest = new ResourceTest();
var messageForKey = GetResourceForTesting(ApplicationConstant.WELCOME_KEY);
//Act
string messageFromApp = classUnderTest.GetResources();
//Assert
Assert.AreEqual(messageForKey, messageFromApp);
}
[TestMethod]
public void Test_English_UnitedStates_Culture()
{
//Arrange
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
ResourceTest classUnderTest = new ResourceTest();
var messageForKey = GetResourceForTesting(ApplicationConstant.WELCOME_KEY);
//Act
string messageFromApp = classUnderTest.GetResources();
//Assert
Assert.AreEqual(messageForKey, messageFromApp);
}
/// <summary>
/// Method to get resouce text on Key
/// </summary>
/// <returns>message from Resource file</returns>
private string GetResourceForTesting(string key)
{
var message = Message.ResourceManager.GetString(key);
return message;
}
}
}
Executing test cases and test cases are passed as shown in below Figure 2
Fig 2
Thanks for reading!