xUnit.net: 为什么这2个等价的测试有不同的结果?
xUnit.net: Why do these 2 equivalent tests have different results?
出于某种原因,此利用 InlineData
的测试在 xUnit 中失败:
[Theory]
[InlineData("\uD800", 1)]
public static void HasLength(string s, int length)
{
Assert.Equal(length, s.Length);
}
而这个使用 MemberData
,通过:
public static IEnumerable<object[]> HasLength_TestData()
{
yield return new object[] { "\uD800", 1 };
}
[Theory]
[MemberData(nameof(HasLength_TestData))]
public static void HasLength(string s, int length)
{
Assert.Equal(length, s.Length);
}
这是什么原因?我在 xUnit.net 中发现了错误吗? (我认为这可能与 \uD800
是一个 surrogate character 这一事实有关,并且它在通过 InlineData
时以某种方式被转换为 2 个字符。但不确定为什么。)
不,这不是错误。
如果你想用 UTF-16 表示一个大于 U+FFFF 的值,你需要使用两个 UTF-16 代码单元:一个高代理项(在 0xD800 到 0xDBFF 范围内)后面跟着一个低代理项 (在 0xDC00 到 0xDFFF 范围内)。所以一个高代理人本身是没有意义的。它本身是一个有效的 UTF-16 代码单元,但它只有在后面跟一个低代理项时才有意义。
本文中有更多信息http://codeblog.jonskeet.uk/2014/11/07/when-is-a-string-not-a-string/
Nicolay 的回答没有回答问题,但 link 回答了问题:
属性值使用 UTF-8 存储,孤立的高代理无法从 UTF-16 成功转换。
这是 (VB.NET) LinqPad query 确认情况。
出于某种原因,此利用 InlineData
的测试在 xUnit 中失败:
[Theory]
[InlineData("\uD800", 1)]
public static void HasLength(string s, int length)
{
Assert.Equal(length, s.Length);
}
而这个使用 MemberData
,通过:
public static IEnumerable<object[]> HasLength_TestData()
{
yield return new object[] { "\uD800", 1 };
}
[Theory]
[MemberData(nameof(HasLength_TestData))]
public static void HasLength(string s, int length)
{
Assert.Equal(length, s.Length);
}
这是什么原因?我在 xUnit.net 中发现了错误吗? (我认为这可能与 \uD800
是一个 surrogate character 这一事实有关,并且它在通过 InlineData
时以某种方式被转换为 2 个字符。但不确定为什么。)
不,这不是错误。
如果你想用 UTF-16 表示一个大于 U+FFFF 的值,你需要使用两个 UTF-16 代码单元:一个高代理项(在 0xD800 到 0xDBFF 范围内)后面跟着一个低代理项 (在 0xDC00 到 0xDFFF 范围内)。所以一个高代理人本身是没有意义的。它本身是一个有效的 UTF-16 代码单元,但它只有在后面跟一个低代理项时才有意义。
本文中有更多信息http://codeblog.jonskeet.uk/2014/11/07/when-is-a-string-not-a-string/
Nicolay 的回答没有回答问题,但 link 回答了问题:
属性值使用 UTF-8 存储,孤立的高代理无法从 UTF-16 成功转换。
这是 (VB.NET) LinqPad query 确认情况。