在.NET(VB或C#)中使用Microsoft.VisualStudio.TestTools.UnitTesting
进行单元测试:
如何在单元测试中本地有效地更改区域设置小数分隔符,以便String.Format("{0:0.0}", aDouble)
(AFAIK与区域设置相关)将使用已修改的区域设置生成字符串?
编辑: 观察:我不是问如何输出具有特定语言环境的文本。我问如何在单元测试中更改区域设置的小数分隔符,以便模拟在具有不同小数分隔符的系统中将发生的情况。 我不是从单元测试代码中调用String.Format,而是从测试的功能中调用String.Format。
其他信息:
我在VB中创建一个.NET库,我有一个MyClass
类,其Encode(...)
函数正在编写数字信息作为文本。
该组件将用于不同计算机可能具有“十进制分隔符”(逗号或点)的不同配置的环境中。然而,我的组件应该对此不敏感,这意味着它应该始终输出“point”(例如,在格式化数字时使用System.Globalization.CultureInfo.InvariantCulture
)。
我想编写一个单元测试,以确保即使系统区域设置小数分隔符设置为“逗号”而不是“点”,编码功能仍将继续工作。我做了一些研究,得出了类似的东西:
Public Sub Encode_CultureWithCommaSeparator_OutputMatchesTemplate() ... Dim oldCulture = Threading.Thread.CurrentThread.CurrentCulture ' A culture that uses "," as decimal separator Threading.Thread.CurrentThread.CurrentCulture = New Globalization.CultureInfo("es-ES") CompareEncodedToTemplate(...) Threading.Thread.CurrentThread.CurrentCulture = oldCulture End Sub
CompareEncodedToTemplate
函数将使用MyClass.Encode
方法将信息写入MemoryStream
,然后将其与每行的模板文本文件行进行比较,当它们不相等时,测试就会失败。
我想“模拟”的是当语言环境的小数分隔符不同于“点”时,Encode
函数的运行方式。显然我的测试功能没有像我预期的那样工作:
我在计算机上运行测试,其中小数点分隔符设置为指向,测试成功,所以我认为“我的编码功能将按我的意愿工作,因为测试通过了”。
然而,我在计算机上运行测试,并将小数分隔符设置为逗号,测试失败。我意识到这是因为在Encode
逻辑中,我在格式化双精度时错过了使用InvariantCulture
。这意味着我的测试没有按预期工作,因为我应该能够在第一台计算机上检测到这种情况(因为这是我想要创建测试的原因)。
提前谢谢。
答案 0 :(得分:2)
您应该考虑使用NumberFormatInfo
这样:
var nfi = new System.Globalization.NumberFormatInfo();
nfi.NumberDecimalSeparator = ",";
var formatted = (10.01).ToString("N", nfi);
注意:NumberFormatInfo
包含货币与其他数字的单独设置
:https://msdn.microsoft.com/en-us/library/system.globalization.numberformatinfo(v=vs.110).aspx
答案 1 :(得分:2)
使用我的开发机器与CI服务器完全解决这个问题。我编写了以下结构来帮助:
public struct CultureContext : IDisposable
{
public static readonly CultureInfo CommaCulture = new CultureInfo("en-us")
{
NumberFormat =
{
CurrencyDecimalSeparator = ",",
NumberDecimalSeparator = ",",
PercentDecimalSeparator = ","
}
};
public static readonly CultureInfo PointCulture = new CultureInfo("en-us")
{
NumberFormat =
{
CurrencyDecimalSeparator = ".",
NumberDecimalSeparator = ".",
PercentDecimalSeparator = "."
}
};
private readonly CultureInfo _originalCulture;
public CultureContext(CultureInfo culture)
{
_originalCulture = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = culture;
}
public void Dispose()
{
Thread.CurrentThread.CurrentCulture = _originalCulture;
}
public static void UnderBoth(Action test)
{
using (new CultureContext(PointCulture))
{
test();
}
using (new CultureContext(CommaCulture))
{
test();
}
}
}
然后你可以测试它:
CultureContext.UnderBoth(() => Assert.AreEqual("1.1", sut.ToString()));
答案 2 :(得分:0)
据我所知,使用"{0.0}"
格式化字符串将始终呈现为小数。
String.Format("{0:0}", 1.3); // Prints 1.3 regardless of culture
您必须更具体地指定它:
String.Format("{0:f}", 1.3); // Prints 1,3 if de-DE for example
请参阅字符串here的标准数字格式。然后根据单元测试范围上下文中的当前文化,它将相应地呈现字符串。
例如:
- 1234.567(“F”,en-US) - > 1234.57
- 1234.567(“F”,de-DE) - > 1234,57
- 1234(“F1”,en-US) - > 1234.0
- 1234(“F1”,de-DE) - > 1234,0
在上述链接中有无数格式化数字的例子。我希望你觉得这很有帮助。
答案 3 :(得分:0)
这是一个有你所描述的方法的类:
public class Class1
{
public string FormatSpecial(double d) {
return string.Format("{0:0.0}", d);
}
}
以下是我的单元测试:
[TestClass]
public class UnitTest1
{
Sample.Class1 instance;
[TestInitialize]
public void InitTests()
{
instance = new Sample.Class1();
}
[TestMethod]
public void TestMethod1()
{
var result = instance.FormatSpecial(5.25);
Assert.AreEqual("5.3", result);
}
[TestMethod]
public void TestMethod2()
{
Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.GetCultureInfo("es-ES");
var result = instance.FormatSpecial(5.25);
Assert.AreEqual("5,3", result);
}
}
这两个测试都成功执行。
技巧是在运行您正在测试的操作之前为测试中的线程设置文化信息。