即使预期和实际相同,Assert.AreEqual也会失败

时间:2009-05-25 15:23:57

标签: .net unicode

我有以下测试似乎产生相同的字符串,但Assert.AreEqual失败。

[TestMethod]
public void Decompressed_test_should_equal_to_text_before_compression()
{
    TextCompressor compressor = new TextCompressor();
    Random r = new Random((int)DateTime.Now.Ticks);

    for (int i = 500; i < 1500; i++)
    {
        char[] testArray = new char[i];

        for (int j = 0; j < i; j++)
        {                    
            char randomChar = (char)(r.Next(256, 65536));
            testArray[j] = randomChar;
        }
        string testString = new String(testArray);
        string compressed = compressor.Compress(testString);
        string decompressed = compressor.Decompress(compressed);

        Assert.AreEqual(testString.Length, decompressed.Length);
        Assert.AreEqual(testString, decompressed, false, CultureInfo.InvariantCulture);
    }
}

compress.Compress和compress.Decompress使用GZipStream进行一些压缩和解压缩。

如果我尝试(65,90)而不是(256,65536),它通过,所以我猜它与unicode有关。我尝试过CurrentCulture而没有文化,而不是InvariantCulture,它仍然失败。但结果字符串看起来是一样的:

Assert.AreEqual失败。

预期:

&LT;☔ฺ疉鎷얚᧏跨꿌沩얫嘹֨ز항们嵜浮䑹شم霭斳薃픢萁⯬쫎ʛ⫕蝺ꄗ稣넢뇌䶆멊큀퉆䐫̥괊 ⑆놸侥̅ᵀ㣚ꢅ뺓䇚녚伀讍홬䈕캾撏Ჴ孢黮摠뮡䌦윃ᬳ狚䆙툾훶䏤ꛈṻ⟧㉖鮸蒵萗냤퇅서㪨潋鰪残䓴ۇ넃櫜㑦䢻쮓죣䕱䶘㴝姳뿝嘼ᷨ㗬꺬櫣涷꠶浒껅က㷕䩉毎覛⧹䮯嬇힚艐Ὑ쇕횻鸙蹻硐䈆쓖⸛錼鰙ኰ乒֐⺴썓힠䵓ꅄⵈ 桃怅㾈枟⏠ه폫ا琖ퟰ乼쩐鑈푷᫇﯎蕱늛쭡䙠ⲓᒇꪮ툅⃑ꦴ돻♹ᢋ麝熪뚭Ћ䌚娯钮⡃㪿ㅞ⤩㥍车䎘磛蚾ㅸ擫떦蝳分鰽䠺ꭍ튘폻⥽ⳉ历⹼驿똮⯴⋟Ḋ᛼룴꣜墭䐣앾郢ᵸᮄ杗夺騑硼佑烑鄗䳘핬溴墽炁ࣘヲ栥풼ಃ斗狭就쵎⃺嬒瀃碂밎崹䎐貇஛汫踖뢸숥퍞르뗿䭯䖝䱅䵱꽔븽䢴ꁅ⟼蒠癸ꩽ靔临䚝!⩏￸鍁Ꮨ䷇쁐쨒ʊ쪦郑借滋铆ᮉ嚃ᩨ ⶝ိ펇ꮼ뇄』ᰉ㕾桠鯅蛱䠿櫄筑픆车똅 ㈆ّἋ荞괋랆偦뤰䝷핸⹝屑素虱怀猔勋碉퀪睹Ⓥ䍙ಗ䤮뾿谢ꁼ戻ڳᆯ콧逼ز븭碇쮢籍⁜왋壝骂暷샖଄ࣵ舻᜝䃴厫ᢉ慨䁆ꂴ೉溘欋옭螶䦗跠﨔膉痹邘⋫吪멚埣ꯕ扌옘广犵肖街㶕畅몡ↇ꠫褴픧ၥ帻놤ਰ惘똞颤籴쫼鿋 䬝获⺁峁踷锝副鰀唝⹀谲迟䩢푑팾糔뭯዇ࣷ䷴䬾갭ⶵ틩鲀㵻恬҅པᣄⲪ豩뛌꛵㥨몙〼△⏮큤亃ꢡ 웼ఐ칇뻻펂㢓吋䂃䨠䕱&GT;

实际值:

&LT;☔ฺ疉鎷얚᧏跨꿌沩얫嘹֨ز항们嵜浮䑹شم霭斳薃픢萁⯬쫎ʛ⫕蝺ꄗ稣넢뇌䶆멊큀퉆䐫̥괊 ⑆놸侥̅ᵀ㣚ꢅ뺓䇚녚伀讍홬䈕캾撏Ჴ孢黮摠뮡䌦윃ᬳ狚䆙툾훶䏤ꛈṻ⟧㉖鮸蒵萗냤퇅서㪨潋鰪残䓴ۇ넃櫜㑦䢻쮓죣䕱䶘㴝姳뿝嘼ᷨ㗬꺬櫣涷꠶浒껅က㷕䩉毎覛⧹䮯嬇힚艐Ὑ쇕횻鸙蹻硐䈆쓖⸛錼鰙ኰ乒֐⺴썓힠䵓ꅄⵈ 桃怅㾈枟⏠ه폫ا琖ퟰ乼쩐鑈푷᫇﯎蕱늛쭡䙠ⲓᒇꪮ툅⃑ꦴ돻♹ᢋ麝熪뚭Ћ䌚娯钮⡃㪿ㅞ⤩㥍车䎘磛蚾ㅸ擫떦蝳分鰽䠺ꭍ튘폻⥽ⳉ历⹼驿똮⯴⋟Ḋ᛼룴꣜墭䐣앾郢ᵸᮄ杗夺騑硼佑烑鄗䳘핬溴墽炁ࣘヲ栥풼ಃ斗狭就쵎⃺嬒瀃碂밎崹䎐貇஛汫踖뢸숥퍞르뗿䭯䖝䱅䵱꽔븽䢴ꁅ⟼蒠癸ꩽ靔临䚝!⩏￸鍁Ꮨ䷇쁐쨒ʊ쪦郑借滋铆ᮉ嚃ᩨ ⶝ိ펇ꮼ뇄』ᰉ㕾桠鯅蛱䠿櫄筑픆车똅 ㈆ّἋ荞괋랆偦뤰䝷핸⹝屑素虱怀猔勋碉퀪睹Ⓥ䍙ಗ䤮뾿谢ꁼ戻ڳᆯ콧逼ز븭碇쮢籍⁜왋壝骂暷샖଄ࣵ舻᜝䃴厫ᢉ慨䁆ꂴ೉溘欋옭螶䦗跠﨔膉痹邘⋫吪멚埣ꯕ扌옘广犵肖街㶕畅몡ↇ꠫褴픧ၥ帻놤ਰ惘똞颤籴쫼鿋 䬝获⺁峁踷锝副鰀唝⹀谲迟䩢푑팾糔뭯዇ࣷ䷴䬾갭ⶵ틩鲀㵻恬҅པᣄⲪ豩뛌꛵㥨몙〼△⏮큤亃ꢡ 웼ఐ칇뻻펂㢓吋䂃䨠䕱&GT;

我错过了什么?

4 个答案:

答案 0 :(得分:2)

(char)(r.Next(256, 65536))会产生无效的字符组合,导致非法文本,因此您无法使用它来创建测试内容。即使转换有效并且生成有效字符,也可能发生这种情况。一个例子是U + D800到U + DFFF的代理人,但可能还有其他人。

如果要从所有Unicode范围生成示例文本,则必须在创建时识别Unicode,而不是仅将其随机转换为char。 (当你在问题中说明当你为随机数提供更窄的范围时,它可以解决这个问题。)

答案 1 :(得分:1)

使用byte而非char

您的Compress/Decompress方法应该使用byte[]数组,无论调用它们应该读取您的Unicode数据并在调用它们之前进行翻译。

您知道.NET 2.0以上包含GZipStream类吗?

答案 2 :(得分:1)

做了一些实验:

string testString = new String(testArray);
string anotherString = new String(testArray);
Assert.AreEqual(testString.Length, anotherString.Length);
Assert.AreEqual(testString, anotherString, false, CultureInfo.InvariantCulture);

这是没有压缩的。它工作正常。

我建议你把测试改为:

for (int i = 256; i < 65536; i++)
{
  string testString = new String((char)(i), 2);

  string compressed = compressor.Compress(testString);
  string decompressed = compressor.Decompress(compressed);

  Assert.AreEqual(testString.Length, decompressed.Length);
  Assert.AreEqual(testString, decompressed, false, CultureInfo.InvariantCulture);
}

这一次只测试一个字符,你没有随机值(没有“有时工作”的问题),你会看到是否有某种字符无效。

答案 3 :(得分:0)

我对加密/解密有相同的测试。

使用二分法,我发现任何包含“代理代码点”的字符串都是U + 55296到U + 57343范围内的Unicode字符,将无法使用Assert.AreEqual

所以您可以使用的最宽范围是:

char randomChar = (char)(r.Next(0, 55295));

char randomChar = (char)(r.Next(57344, 65535));