কাঠামোগুলির তুলনা করার সময় কেন এই দাবী একটি ফর্ম্যাট ব্যতিক্রম ছুঁড়ে ফেলে?


94

আমি দুটি System.Drawing.Sizeকাঠামোর সমতা জোর দেওয়ার চেষ্টা করছি এবং আমি প্রত্যাশিত দাবি ব্যর্থতার পরিবর্তে একটি ফর্ম্যাট ব্যতিক্রম পাচ্ছি।

[TestMethod]
public void AssertStructs()
{
    var struct1 = new Size(0, 0);
    var struct2 = new Size(1, 1);

    //This throws a format exception, "System.FormatException: Input string was not in a correct format."
    Assert.AreEqual(struct1, struct2, "Failed. Expected {0}, actually it is {1}", struct1, struct2); 

    //This assert fails properly, "Failed. Expected {Width=0, Height=0}, actually it is {Width=1, Height=1}".
    Assert.AreEqual(struct1, struct2, "Failed. Expected " + struct1 + ", actually it is " + struct2); 
}

এই উদ্দেশ্যমূলক আচরণ? আমি কি এখানে কিছু ভুল করছি?


আপনি চেষ্টা করেছেন Assert.AreEqual(struct1, struct2, string.Format("Failed expected {0} actually is {1}, স্ট্রাক্ট 1.টিস্ট্রিং (), স্ট্রাক্ট 2.টোস্ট্রিং ()) `?
ডিস্কজঙ্কি

এটা ভাল কাজ করে; তবে আমি কেন আগ্রহী তা সম্পর্কে কেন আগ্রহী।
কাইল

কাইল কৌতূহলের বাইরে, এটি ইউনিট টেস্টিং ফ্রেমওয়ার্কের সিলভারলাইট সামঞ্জস্যপূর্ণ সংস্করণের সাথে নয়, তাই না? আমি এই ডিএলএলগুলির সাথে এটি পুনরুত্পাদন করতে পারি (এখনও পুরো .NET ফ্রেমওয়ার্ক সংস্করণটি চেষ্টা করে দেখিনি) সম্পাদনা: কিছুই নয়, সম্পূর্ণগুলি নিয়েও পরীক্ষা করা হয়েছে এবং এখনও ব্যর্থ হয়েছে। :)
ক্রিস সিনক্লেয়ার

@ ক্রিসসিনক্লেয়ার নাহ, এটি ভিজুয়াল স্টুডিও ২০১০ চূড়ান্তের সাথে আসা ম্যাসেস্টের যে কোনও সংস্করণ ব্যবহার করছে। পরীক্ষা প্রকল্পটি নিজেই লক্ষ্যবস্তু করছে। নেট ফ্রেমওয়ার্ক 4
কাইল

4
আপনি কোনও অভিশাপ দিচ্ছেন কিনা তা নিশ্চিত নন, তবে এটি ইউএনইটিতে ভাল কাজ করে। আমি এমএসেস্টে এর মতো আরও "ইস্যু" দেখেছি। ইউনাইট কিছুটা পরিপক্ক বলে মনে হচ্ছে (কমপক্ষে আমার কাছে)। পোস্টের জন্য +1
bas

উত্তর:


100

আমি এইটা পাইছি. এবং হ্যাঁ, এটি একটি বাগ।

সমস্যাটি হ'ল দুটি স্তর রয়েছে string.Format চলছে।

প্রথম ফর্ম্যাটিং মাত্রা ভালো কিছু হল:

string template  = string.Format("Expected: {0}; Actual: {1}; Message: {2}",
                                 expected, actual, message);

তারপরে আমরা string.Formatসরবরাহিত প্যারামিটারগুলি সহ আমরা ব্যবহার করি :

string finalMessage = string.Format(template, parameters);

(স্পস্টত: ই অনেক সংস্কৃতির প্রদান করা হচ্ছে, এবং কিছু sanitization সাজানোর ... কিন্তু যথেষ্ট নয়।)

এটি দুর্দান্ত দেখাচ্ছে - যদি না প্রত্যাশিত এবং আসল মানগুলি নিজেরাই বন্ধনীতে শেষ হয় তবে স্ট্রিংয়ে রূপান্তরিত হওয়ার পরে - যা তারা করে Size। উদাহরণস্বরূপ, আপনার প্রথম আকারটি রূপান্তরিত হয়ে শেষ:

{Width=0, Height=0}

সুতরাং দ্বিতীয় স্তরের বিন্যাসটি হ'ল কিছু:

string.Format("Expected: {Width=0, Height=0}; Actual: {Width=1, Height=1 }; " +
              "Message = Failed expected {0} actually is {1}", struct1, struct2);

... এবং এটিই ব্যর্থ। আউচ।

প্রকৃতপক্ষে, আমরা প্রত্যাশিত এবং আসল অংশগুলির জন্য আমাদের পরামিতিগুলি ব্যবহার করতে ফর্ম্যাটটিকে বোকা বানিয়ে এটি খুব সহজেই প্রমাণ করতে পারি:

var x = "{0}";
var y = "{1}";
Assert.AreEqual<object>(x, y, "What a surprise!", "foo", "bar");

ফলাফল হলো:

Assert.AreEqual failed. Expected:<foo>. Actual:<bar>. What a surprise!

স্পষ্টতই ভাঙ্গা, যেমন আমরা প্রত্যাশা করি fooনা বা আসল মূল্যও ছিল না bar!

মূলত এটি এসকিউএল ইঞ্জেকশন আক্রমণ হিসাবে, তবে এর চেয়ে কম ভীতিজনক প্রসঙ্গে string.Format

string.Formatকার্যবিহীন হিসাবে , আপনি স্ট্রিপলিং ওয়ারিয়র পরামর্শ হিসাবে ব্যবহার করতে পারেন । এটি প্রকৃত / প্রত্যাশিত মানগুলির সাথে ফর্ম্যাট করার ফলাফলের জন্য দ্বিতীয় স্তরের ফর্ম্যাটিং এড়ানো হয়।


জনের বিস্তারিত উত্তরের জন্য ধন্যবাদ! আমি প্রায় স্ট্রিপলিং ওয়ারিয়র্স কাজ ব্যবহার করে শেষ করেছি।
কাইল

4
%*nসমমান নেই ? :(
টম হাটিন - 19:58

কেউ কি এর জন্য বাগ রিপোর্ট জমা দিয়েছে?
কেভিন

@ কেভিন: হ্যাঁ - যদিও অভ্যন্তরীণভাবে, তবে এটি স্থির না হওয়া পর্যন্ত অগ্রগতি সর্বজনীনভাবে দৃশ্যমান হবে কিনা তা আমি নিশ্চিত নই।
জন স্কিটি

4
@ কেভিন আমি একবার এমএস-এ রেখেছিলাম যখন এটির বাগ নিশ্চিত হয়ে গেছে। আপনি যদি এটি সর্বজনীনভাবে ট্র্যাক করতে চান তবে কান্টে.মাইক্রোসফট / ভিজ্যুয়ালস্টুডিও / ফেডব্যাক / ডেটেল / 9595৯৯২৮ /
কাইল

43

আমি মনে করি আপনি একটি বাগ খুঁজে পেয়েছেন।

এটি কাজ করে (দৃ exception় ব্যতিক্রম ছোঁড়ে):

var a = 1;
var b = 2;
Assert.AreEqual(a, b, "Not equal {0} {1}", a, b);

এবং এটি কাজ করে (বার্তা আউটপুট করে):

var a = new{c=1};
var b = new{c=2};
Console.WriteLine(string.Format("Not equal {0} {1}", a, b));

তবে এটি কাজ করে না (একটি ছুড়ে ফেলে FormatException):

var a = new{c=1};
var b = new{c=2};
Assert.AreEqual(a, b, "Not equal {0} {1}", a, b);

এই কোনও প্রত্যাশিত আচরণ হতে পারে এমন কোনও কারণ আমি ভাবতে পারি না। আমি একটি বাগ রিপোর্ট জমা দিতে হবে। ইতিমধ্যে, এখানে একটি কার্যনির্বাহী:

var a = new{c=1};
var b = new{c=2};
Assert.AreEqual(a, b, string.Format("Not equal {0} {1}", a, b));

5

আমি @ স্ট্রিপলিং ওয়ারিয়র এর সাথে একমত হই যে এটি কমপক্ষে 2 টি ওভারলোডের উপর Assert.AreEqual () পদ্ধতিতে সত্যই কোনও বাগ হিসাবে দেখা যাচ্ছে to স্টিপলিং ওয়ারিয়র ইতিমধ্যে উল্লেখ করেছে যে, নিম্নলিখিত ব্যর্থ হয়েছে;

var a = new { c = 1 };
var b = new { c = 2 };
Assert.AreEqual(a, b, "Not equal {0} {1}", a, b);

কোড ব্যবহারে একটু বেশি স্পষ্ট হওয়ার বিষয়ে আমি এই বিষয়ে আরও কিছু পরীক্ষা-নিরীক্ষা করে যাচ্ছি। নিম্নলিখিতগুলিও কাজ করে না;

// specify variable data type rather than "var"...no effect, still fails
Size a = new Size(0, 0);
Size b = new Size(1, 1);
Assert.AreEqual(a, b, "Not equal {0} {1}", a, b);

এবং

// specify variable data type and name the type on the generic overload of AreEqual()...no effect, still fails
Size a = new Size(0, 0);
Size b = new Size(1, 1);
Assert.AreEqual<Size>(a, b, "Not equal {0} {1}", a, b);

এটি আমার চিন্তাভাবনা পেয়েছে। সিস্টেম.ড্রেইং.সাইজ একটি স্ট্রাক্ট। বস্তুর কী হবে? PARAM তালিকা নেই উল্লেখ যে পরে তালিকা stringবার্তা params object[]। টেকনিক্যালি, হ্যাঁ structs মধ্যে হয় বস্তু ... কিন্তু বিশেষ ধরণের বস্তুর, অর্থাত্, মান ধরনের। আমি মনে করি এটি এখানেই বাগ রয়েছে। আমরা একটি অনুরূপ ব্যবহার এবং গঠন সঙ্গে আমাদের নিজস্ব বস্তু ব্যবহার করেন তাহলে Sizeনিম্নলিখিত আসলে আছে কাজ;

private class MyClass
{
    public MyClass(int width, int height)
        : base()
    { Width = width; Height = height; }

    public int Width { get; set; }
    public int Height { get; set; }
}

[TestMethod]
public void TestMethod1()
{
    var test1 = new MyClass(0, 0);
    var test2 = new MyClass(1, 1);
    Assert.AreEqual(test1, test2, "Show me A [{0}] and B [{1}]", test1, test2);
}

4
সমস্যাটি এটি কিনা classবা তা নয় struct, তবে ToStringমানটিতে কোঁকড়ানো বন্ধনী রয়েছে কিনা তা দেখতে এটির মতো নয় String.Format
জিন হোমিনাল

3

আমি মনে করি প্রথম দাবিটি ভুল।

পরিবর্তে এটি ব্যবহার করুন:

Assert.AreEqual(struct1, 
                struct2, 
                string.Format("Failed expected {0} actually is {1}", struct1, struct2));

ডকুমেন্টেশন অনুসারে আমার বিন্যাসিত স্ট্রিংয়ের সাথে আরেইকুয়াল কল করা উচিত। msdn.microsoft.com/en-us/library/ms243436%28v=vs.100%29.aspx , বিশেষত পরামিতি প্রকার: সিস্টেম.অবজেক্ট [] বার্তা ফর্ম্যাট করার সময় প্যারামিটারগুলির একটি অ্যারে ব্যবহার করা।
কাইল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.