NUnit এ দুটি বস্তুর মধ্যে সমতার তুলনা করুন


126

আমি দৃsert়ভাবে চেষ্টা করার চেষ্টা করছি যে একটি বস্তু অন্য বস্তুর সাথে "সমান"।

বস্তুগুলি হ'ল একগুচ্ছ সার্বজনীন সম্পত্তি সহ এক শ্রেণীর উদাহরণ। বৈশিষ্ট্যের উপর ভিত্তি করে NUnit সমতা দাবী করার কোন সহজ উপায় আছে?

এটি আমার বর্তমান সমাধান তবে আমি মনে করি এর থেকে আরও ভাল কিছু হতে পারে:

Assert.AreEqual(LeftObject.Property1, RightObject.Property1)
Assert.AreEqual(LeftObject.Property2, RightObject.Property2)
Assert.AreEqual(LeftObject.Property3, RightObject.Property3)
...
Assert.AreEqual(LeftObject.PropertyN, RightObject.PropertyN)

আমি যা যাচ্ছি তা কালেকশনএকুইভ্যালেন্টকন্ট্রেন্টের মতো একই আত্মায় থাকবে যেখানে নুনিট যাচাই করে যে দুটি সংগ্রহের বিষয়বস্তু অভিন্ন।

উত্তর:


51

ওভাররাইড করুন। আপনার অবজেক্টের জন্য এবং ইউনিটের পরীক্ষায় আপনি কেবল এটি করতে পারেন:

Assert.AreEqual(LeftObject, RightObject);

অবশ্যই, এর অর্থ হতে পারে আপনি কেবলমাত্র সমস্ত পৃথক তুলনাগুলিকে কেবলমাত্র একক পদ্ধতিতে সরিয়ে নিয়েছেন, তবে এটি আপনাকে একাধিক পরীক্ষার জন্য এই প্রয়োগটি পুনরায় ব্যবহার করতে দেয় এবং অবজেক্টগুলি যে কোনও উপায়ে ভাইবোনদের সাথে নিজেকে তুলনা করতে সক্ষম হবে কিনা তা সম্ভবত বোধগম্য হয়।


2
ধন্যবাদ, লাসেভেক এটি আমার পক্ষে কাজ করেছিল! আমি নির্দেশিকা এখানে অনুযায়ী .Equals বাস্তবায়িত: msdn.microsoft.com/en-us/library/336aedhh(VS.80).aspx
মাইকেল হরেন

12
এবং গেটহ্যাশকোড (), স্পষ্টতই ;
মার্ক

এই পৃষ্ঠার তালিকার 1 নম্বরটি হ'ল গেটহ্যাশকোডকে ওভাররাইড করা এবং তিনি বলেছিলেন যে তিনি এই নির্দেশিকাগুলি অনুসরণ করেছেন :) তবে হ্যাঁ, এটিকে এড়িয়ে যাওয়ার সাধারণ ভুল। সাধারণত কোনও ভুল আপনি বেশিরভাগ সময় লক্ষ্য করবেন না, তবে আপনি যখন করেন, ঠিক সেই সময়গুলির মতো এটি যখন আপনি বলেন "ওহ, আরে, এই সাপটি কেন আমার ট্রাউজারটি তুলেছে এবং কেন সে আমার পাছায় কামড়াচ্ছে"।
লাসে ভি কার্লসেন

1
একটি গুরুত্বপূর্ণ সতর্কবাণী: যদি আপনার অবজেক্টটি প্রয়োগ করে তবে IEnumerableএটিকে ওভাররাইডিং বাস্তবায়নগুলি বিবেচনা না করে একটি সংগ্রহ হিসাবে তুলনা করা হবে Equalsকারণ ইউনাইট IEnumerableউচ্চতর অগ্রাধিকার দেয় । NUnitEqualityComparer.AreEqualবিশদ জন্য পদ্ধতি দেখুন । সমতা সীমাবদ্ধতার একটি Using()পদ্ধতি ব্যবহার করে আপনি তুলনাকারীকে ওভাররাইড করতে পারেন । তারপরেও, IEqualityComparerঅ্যাডাপ্টার নুনিট ব্যবহারের কারণে এটি অ-জেনেরিক বাস্তবায়নের পক্ষে যথেষ্ট নয় ।
কালেব পেডারসন

13
আরও সতর্কতা: GetHashCode()আপনি যদি কখনও সেই জিনিসটিকে কী হিসাবে ব্যবহার করেন তবে পরিবর্তনীয় ধরণের উপর প্রয়োগ করা খারাপ ব্যবহার করবে। এই প্রোগ্রামটিতে, ওভার-রাইড Equals(), GetHashCode()এবং মাত্র পরীক্ষা অর্থে দেখা যায় না জন্য বস্তু অপরিবর্তনীয় হয়।
বাভাজা

118

আপনি যদি কোনও কারণে সমানকে ওভাররাইড করতে না পারেন তবে আপনি এমন একটি সহায়ক পদ্ধতি তৈরি করতে পারেন যা প্রতিচ্ছবি দ্বারা জনসাধারণের বৈশিষ্ট্যগুলিতে পুনরাবৃত্তি করে এবং প্রতিটি সম্পত্তি যুক্ত করে দিতে পারে। এটার মতো কিছু:

public static class AssertEx
{
    public static void PropertyValuesAreEquals(object actual, object expected)
    {
        PropertyInfo[] properties = expected.GetType().GetProperties();
        foreach (PropertyInfo property in properties)
        {
            object expectedValue = property.GetValue(expected, null);
            object actualValue = property.GetValue(actual, null);

            if (actualValue is IList)
                AssertListsAreEquals(property, (IList)actualValue, (IList)expectedValue);
            else if (!Equals(expectedValue, actualValue))
                Assert.Fail("Property {0}.{1} does not match. Expected: {2} but was: {3}", property.DeclaringType.Name, property.Name, expectedValue, actualValue);
        }
    }

    private static void AssertListsAreEquals(PropertyInfo property, IList actualList, IList expectedList)
    {
        if (actualList.Count != expectedList.Count)
            Assert.Fail("Property {0}.{1} does not match. Expected IList containing {2} elements but was IList containing {3} elements", property.PropertyType.Name, property.Name, expectedList.Count, actualList.Count);

        for (int i = 0; i < actualList.Count; i++)
            if (!Equals(actualList[i], expectedList[i]))
                Assert.Fail("Property {0}.{1} does not match. Expected IList with element {1} equals to {2} but was IList with element {1} equals to {3}", property.PropertyType.Name, property.Name, expectedList[i], actualList[i]);
    }
}

@ ওয়েসলি: এটি সত্য নয়। Type.GetProperties পদ্ধতি: বর্তমান প্রকারের সমস্ত পাবলিক বৈশিষ্ট্য প্রদান করে। দেখুন msdn.microsoft.com/en-us/library/aky14axb.aspx
Sergii Volchkov

4
ধন্যবাদ। যাইহোক, আমাকে আসল এবং প্রত্যাশিত প্যারামগুলির ক্রমটি স্যুইচ করতে হয়েছিল যেহেতু কনভার্ভেশন হ'ল প্রত্যাশিতটি বাস্তবের আগে প্যারাম।
ভালামাস

এটি আইএমএইচও, ইক্যুয়াল এবং হ্যাশকোড ওভাররাইডগুলি প্রতিটি ক্ষেত্রের সাথে তুলনা করার উপর ভিত্তি করে তৈরি করা উচিত নয় এবং প্রতিটি বস্তু জুড়ে করা খুব ক্লান্তিকর। ভাল করেছ!
স্কট হোয়াইট

3
এটি দুর্দান্ত কাজ করে যদি আপনার ধরণের কেবল বৈশিষ্ট্য হিসাবে প্রাথমিক ধরণ থাকে। তবে যদি আপনার ধরণের কাস্টম প্রকারের সাথে সম্পত্তি থাকে (যা সমানগুলি কার্যকর করে না) এটি ব্যর্থ হবে।
ববি ক্যানন

বস্তুর বৈশিষ্ট্যগুলির জন্য কিছু পুনরাবৃত্তি যোগ করা হয়েছিল, তবে আমাকে
সূচিযুক্ত

113

কেবল পরীক্ষার উদ্দেশ্যেই সমানকে ওভাররাইড করবেন না। এটি ক্লান্তিকর এবং ডোমেন যুক্তিকে প্রভাবিত করে। পরিবর্তে,

বস্তুর ডেটার তুলনা করতে JSON ব্যবহার করুন

আপনার জিনিসগুলিতে কোনও অতিরিক্ত যুক্তি নেই। পরীক্ষার জন্য কোনও অতিরিক্ত কাজ নেই।

কেবল এই সহজ পদ্ধতিটি ব্যবহার করুন:

public static void AreEqualByJson(object expected, object actual)
{
    var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
    var expectedJson = serializer.Serialize(expected);
    var actualJson = serializer.Serialize(actual);
    Assert.AreEqual(expectedJson, actualJson);
}

এটি দুর্দান্ত কাজ করে বলে মনে হচ্ছে। পরীক্ষার রানার ফলাফলের তথ্য JSON স্ট্রিং তুলনা (অবজেক্ট গ্রাফ) অন্তর্ভুক্ত দেখায় যাতে আপনি কী ভুল তা সরাসরি দেখেন।

নোটও! আপনার যদি বৃহত জটিল অবজেক্ট থাকে এবং কেবলমাত্র সেগুলির কিছু অংশের তুলনা করতে চান তবে আপনি উপরের পদ্ধতির সাথে বেনামে অবজেক্ট তৈরি করতে পারেন ( সিক্যুয়েন্স ডেটার জন্য লিনকিউ ব্যবহার করুন )।

public void SomeTest()
{
    var expect = new { PropA = 12, PropB = 14 };
    var sut = loc.Resolve<SomeSvc>();
    var bigObjectResult = sut.Execute(); // This will return a big object with loads of properties 
    AssExt.AreEqualByJson(expect, new { bigObjectResult.PropA, bigObjectResult.PropB });
}

1
এটি পরীক্ষার একটি দুর্দান্ত উপায়, বিশেষত যদি আপনি যাইহোক JSON এর সাথে লেনদেন করেন (যেমন কোনও ওয়েব পরিষেবা অ্যাক্সেস করার জন্য টাইপ করা ক্লায়েন্ট ব্যবহার করে)। এই উত্তরটি আরও বেশি হওয়া উচিত।
রূপেশ শেনয়

1
লিনক ব্যবহার করুন! @ দিমিত্রিবিএলআর (উত্তরের শেষ অনুচ্ছেদটি দেখুন) :)
সর্বাধিক

3
এটি একটি মহান ধারণা। আমি আরও নতুন Json.NET ব্যবহার করব: var अपेक्षित জেসন = নিউটোনসফট.জসন.জসনকনভার্ট.সরিয়ালাইজবজেক্ট (প্রত্যাশিত);
ব্রোকমাইলেগবাইকিং

2
এটি বিজ্ঞপ্তি সংক্রান্ত রেফারেন্সগুলির সাথে কাজ করবে না। JSON পদ্ধতির উপর উন্নত অভিজ্ঞতার পরিবর্তে github.com/kbilsted/StatePrinter ব্যবহার করুন
কার্লো ভি। ড্যাঙ্গো

2
এটি সত্য @ কোকা চেরনভ এবং কখনও কখনও আপনি যদি আদেশটি একই না হয় তবে আপনি পরীক্ষায় ব্যর্থ হতে চান তবে ক্রমটি যদি একইরকম না হয় তবে আপনি ব্যর্থ হতে চান না যদি আপনি আরেকুয়ালবিজেসন পদ্ধতিতে পাস করার আগে তালিকাগুলিতে সুস্পষ্ট বাছাই করতে পারেন (লিনক ব্যবহার করে)। পরীক্ষার আগে আপনার অবজেক্টগুলিকে "পুনর্বিন্যাস" করার একটি সহজ বৈকল্পিক উত্তরের শেষ কোড উদাহরণে। সুতরাং এটি খুব "সার্বজনীন" আমার মনে হয়! :)
সর্বাধিক

91

ফ্লুয়েট অ্যাসেসরেশন লাইব্রেরি ব্যবহার করে দেখুন:

dto.ShouldHave(). AllProperties().EqualTo(customer);

http://www.fluentassertions.com/

এটি নুগেট ব্যবহার করে ইনস্টল করা যেতে পারে।


18
ShouldHave অবমূল্যায়ন করা হয়েছে, তাই dto.ShouldBeEquivalentTo (গ্রাহক) হওয়া উচিত; পরিবর্তে
হোয়াইটনাট

2
এটি এই কারণে সেরা উত্তর ।
টড মেনিয়ার

হ্যাডবিএকুইভ্যালেন্ট বগি :(
কনস্টান্টিন

3
ঠিক একই সমস্যা ছিল এবং নিম্নলিখিতটি কার্যকর হয়েছে বলে মনে হচ্ছে:actual.ShouldBeEquivalentTo(expected, x => x.ExcludingMissingMembers())
stt106

1
এটি একটি মহান lib হয়! সমানকে ওভাররাইড করার প্রয়োজন হয় না এবং এছাড়াও (যদি সমান যেকোনভাবে ওভাররাইড করা হয়, উদাহরণস্বরূপ মান বস্তুর জন্য) সঠিক প্রয়োগের উপর নির্ভর করে না। এছাড়াও পার্থক্যটি দুর্দান্তভাবে মুদ্রিত হয়েছে, যেমন জাভার জন্য হামক্রস্টের মতো।
কেপ

35

আমি কেবল পরীক্ষার সক্ষম করতে ইক্যুয়ালগুলিকে ওভাররাইড না করা পছন্দ করি। ভুলে যাবেন না যে আপনি যদি সমান পরিমাণকে ওভাররাইড করেন তবে আপনাকে গেটহ্যাশকোডকেও ওভাররাইড করতে হবে বা উদাহরণস্বরূপ আপনি যদি কোনও শব্দ ব্যবহার করেন তবে আপনি অপ্রত্যাশিত ফলাফল পেতে পারেন।

আমি উপরের প্রতিচ্ছবি পদ্ধতির মতো করি কারণ এটি ভবিষ্যতে বৈশিষ্ট্য সংযোজন করতে পারে।

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

// Sample class.  This would be in your main assembly.
class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

// Unit tests
[TestFixture]
public class PersonTests
{
    private class PersonComparer : IEqualityComparer<Person>
    {
        public bool Equals(Person x, Person y)
        {
            if (x == null && y == null)
            {
                return true;
            }

            if (x == null || y == null)
            {
                return false;
            }

            return (x.Name == y.Name) && (x.Age == y.Age);
        }

        public int GetHashCode(Person obj)
        {
            throw new NotImplementedException();
        }
    }

    [Test]
    public void Test_PersonComparer()
    {
        Person p1 = new Person { Name = "Tom", Age = 20 }; // Control data

        Person p2 = new Person { Name = "Tom", Age = 20 }; // Same as control
        Person p3 = new Person { Name = "Tom", Age = 30 }; // Different age
        Person p4 = new Person { Name = "Bob", Age = 20 }; // Different name.

        Assert.IsTrue(new PersonComparer().Equals(p1, p2), "People have same values");
        Assert.IsFalse(new PersonComparer().Equals(p1, p3), "People have different ages.");
        Assert.IsFalse(new PersonComparer().Equals(p1, p4), "People have different names.");
    }
}

সমানগুলি নাল মানগুলি পরিচালনা করে না। সমান পদ্ধতিতে আপনার ফেরতের বিবৃতি দেওয়ার আগে আমি নিম্নলিখিতগুলি যুক্ত করব। যদি (x == নাল && y == নাল) true সত্য ফিরে আসে; } যদি (x == নাল || y == নাল) false মিথ্যা প্রত্যাবর্তন; Ull আমি নাল সমর্থন যোগ করার জন্য প্রশ্নটি সম্পাদনা করেছি।
ববি ক্যানন

থ্রো নতুন নটমিলিমিটেড এক্সসেপশন () নিয়ে আমার পক্ষে কাজ করছেন না; গেটহ্যাশকোডে। আইক্যুয়ালি কম্পিউটারের যেভাবেই আমার সেই ফাংশনটি দরকার?
love2code

15

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

Expected string length 2326 but was 2342. Strings differ at index 1729.

পার্থক্যগুলি কোথায় রয়েছে তা নির্ধারণের পক্ষে কমপক্ষে বলতে ব্যথা।

ফ্লুয়েট অ্যাসেসরেশনগুলির অবজেক্ট গ্রাফের তুলনা (অর্থাত্ a.ShouldBeEquivalentTo(b)) দিয়ে আপনি এটি ফিরে পাবেন:

Expected property Name to be "Foo" but found "Bar"

এটা অনেক সুন্দর। এখনই ফ্লুয়েটসেসরেশনস পান , আপনি পরে খুশি হবেন (এবং আপনি যদি এটি অগ্রাহ্য করেন তবে দয়া করে ডিসিএল এর উত্তরকেও উন্নত করুন যেখানে ফ্লুয়েন্টএরসেশনগুলির প্রথম পরামর্শ দেওয়া হয়েছিল)।


9

আমি ক্রিসওয়ক্সল এর সাথে একমত - নিখুঁতভাবে পরীক্ষার উদ্দেশ্যে আপনার মূল কোডে সমান প্রয়োগ করা ভাল নয়।

আপনি যদি সমানগুলি প্রয়োগ করছেন কারণ কিছু অ্যাপ্লিকেশন যুক্তির জন্য এটি প্রয়োজন, তবে এটি ঠিক আছে, তবে বিশৃঙ্খলা পরীক্ষার কোডটি বিশৃঙ্খলাবদ্ধ জিনিস থেকে দূরে রাখুন (পরীক্ষার জন্য একই পরীক্ষার শব্দার্থিকগুলিও আপনার অ্যাপ্লিকেশনটির প্রয়োজনের চেয়ে আলাদা হতে পারে)।

সংক্ষেপে, কেবলমাত্র পরীক্ষার কোডটি আপনার শ্রেণীর বাইরে রাখুন।

প্রতিবিম্ব ব্যবহার করে সম্পত্তিগুলির সাধারণ অগভীর তুলনা বেশিরভাগ শ্রেণীর জন্য পর্যাপ্ত হওয়া উচিত, যদিও আপনার সামগ্রীতে জটিল বৈশিষ্ট্য রয়েছে তবে আপনাকে পুনরাবৃত্তি করতে হবে। যদি নিম্নলিখিত রেফারেন্সগুলি হয় তবে বিজ্ঞপ্তি সংক্রান্ত রেফারেন্স বা অনুরূপ থেকে সাবধান থাকুন।

সেয়ানা


বিজ্ঞপ্তি রেফারেন্স ভাল লাগছে। আপনি যদি ইতিমধ্যে তুলনা গাছটিতে কোনও সামগ্রীর অভিধান রাখেন তবে সহজেই কাটিয়ে ওঠা।
লুকাস বি

6

ইউনাইট ২.৪.২-এ সংযুক্ত সম্পত্তির সীমাবদ্ধতাগুলি এমন কোনও সমাধানের মঞ্জুরি দেয় যা ওপি-র মূলের চেয়ে বেশি পাঠযোগ্য এবং এটি ব্যর্থতার বার্তা তৈরি করে produces এটি কোনওভাবেই জেনেরিক নয়, তবে আপনার যদি খুব বেশি ক্লাসের জন্য এটি করার প্রয়োজন না হয় তবে এটি একটি পর্যাপ্ত সমাধান।

Assert.That(ActualObject, Has.Property("Prop1").EqualTo(ExpectedObject.Prop1)
                          & Has.Property("Prop2").EqualTo(ExpectedObject.Prop2)
                          & Has.Property("Prop3").EqualTo(ExpectedObject.Prop3)
                          // ...

বাস্তবায়নের মতো সাধারণ-উদ্দেশ্য হিসাবে Equalsনয় তবে এটি তার চেয়ে অনেক বেশি ভাল ব্যর্থতার বার্তা দেয়

Assert.AreEqual(ExpectedObject, ActualObject);

4

ম্যাক্স উইকস্ট্রমের জেএসএন সলিউশন (উপরে) আমার কাছে সবচেয়ে সার্থক করে তোলে এটি সংক্ষিপ্ত, পরিষ্কার এবং সবচেয়ে গুরুত্বপূর্ণভাবে এটি কাজ করে। ব্যক্তিগতভাবে যদিও আমি পৃথক পদ্ধতি হিসাবে JSON রূপান্তরটি প্রয়োগ করতে পছন্দ করি এবং ইউনিট পরীক্ষার ভিতরে দৃ as়তাটি আবার রাখি ...

সহায়তা পদ্ধতি:

public string GetObjectAsJson(object obj)
    {
        System.Web.Script.Serialization.JavaScriptSerializer oSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
        return oSerializer.Serialize(obj);
    }

ইউনিট পরীক্ষা :

public void GetDimensionsFromImageTest()
        {
            Image Image = new Bitmap(10, 10);
            ImageHelpers_Accessor.ImageDimensions expected = new ImageHelpers_Accessor.ImageDimensions(10,10);

            ImageHelpers_Accessor.ImageDimensions actual;
            actual = ImageHelpers_Accessor.GetDimensionsFromImage(Image);

            /*USING IT HERE >>>*/
            Assert.AreEqual(GetObjectAsJson(expected), GetObjectAsJson(actual));
        }

এফওয়াইআই - আপনার সমাধানে আপনার সিস্টেমের একটি রেফারেন্স যুক্ত করতে হবে e ওয়েব E এক্সটেনশনগুলি।


4

এটি বেশ পুরানো থ্রেড তবে আমি ভাবছিলাম যে কোনও উত্তর প্রস্তাবিত হওয়ার কারণ নেই NUnit.Framework.Is.EqualToএবং NUnit.Framework.Is.NotEqualTo?

যেমন:

Assert.That(LeftObject, Is.EqualTo(RightObject)); 

এবং

Assert.That(LeftObject, Is.Not.EqualTo(RightObject)); 

4
কারণ এটি কী আলাদা তার বিশদটি মুদ্রণ করে না
শ্রাজ স্মিলিউটিজ

1

অন্য বিকল্পটি হ'ল নুনিট বিমূর্ত Constraintশ্রেণি প্রয়োগ করে একটি কাস্টম সীমাবদ্ধতা লিখুন । একটি সামান্য সিনট্যাকটিক চিনি সরবরাহ করতে সহায়ক শ্রেণীর সাহায্যে, ফলাফলের পরীক্ষার কোডটি সুখকরভাবে প্রসারিত এবং পাঠযোগ্য

Assert.That( LeftObject, PortfolioState.Matches( RightObject ) ); 

চূড়ান্ত উদাহরণের জন্য, বিবেচনা করুন যে ক্লাসে 'কেবল পঠনযোগ্য' সদস্য রয়েছে, তা নয় IEquatableএবং আপনি চাইলেও পরীক্ষার অধীনে শ্রেণিটি পরিবর্তন করতে পারেন নি:

public class Portfolio // Somewhat daft class for pedagogic purposes...
{
    // Cannot be instanitated externally, instead has two 'factory' methods
    private Portfolio(){ }

    // Immutable properties
    public string Property1 { get; private set; }
    public string Property2 { get; private set; }  // Cannot be accessed externally
    public string Property3 { get; private set; }  // Cannot be accessed externally

    // 'Factory' method 1
    public static Portfolio GetPortfolio(string p1, string p2, string p3)
    {
        return new Portfolio() 
        { 
            Property1 = p1, 
            Property2 = p2, 
            Property3 = p3 
        };
    }

    // 'Factory' method 2
    public static Portfolio GetDefault()
    {
        return new Portfolio() 
        { 
            Property1 = "{{NONE}}", 
            Property2 = "{{NONE}}", 
            Property3 = "{{NONE}}" 
        };
    }
}

Constraintশ্রেণীর জন্য চুক্তির জন্য একজনকে ওভাররাইড করতে হবে Matchesএবং WriteDescriptionTo(কোনও অমিলের ক্ষেত্রে, প্রত্যাশিত মানের জন্য একটি আখ্যান) তবে ওভাররাইডিং WriteActualValueTo(প্রকৃত মানের জন্য আখ্যান) অর্থবোধ করে:

public class PortfolioEqualityConstraint : Constraint
{
    Portfolio expected;
    string expectedMessage = "";
    string actualMessage = "";

    public PortfolioEqualityConstraint(Portfolio expected)
    {
        this.expected = expected;
    }

    public override bool Matches(object actual)
    {
        if ( actual == null && expected == null ) return true;
        if ( !(actual is Portfolio) )
        { 
            expectedMessage = "<Portfolio>";
            actualMessage = "null";
            return false;
        }
        return Matches((Portfolio)actual);
    }

    private bool Matches(Portfolio actual)
    {
        if ( expected == null && actual != null )
        {
            expectedMessage = "null";
            expectedMessage = "non-null";
            return false;
        }
        if ( ReferenceEquals(expected, actual) ) return true;

        if ( !( expected.Property1.Equals(actual.Property1)
                 && expected.Property2.Equals(actual.Property2) 
                 && expected.Property3.Equals(actual.Property3) ) )
        {
            expectedMessage = expected.ToStringForTest();
            actualMessage = actual.ToStringForTest();
            return false;
        }
        return true;
    }

    public override void WriteDescriptionTo(MessageWriter writer)
    {
        writer.WriteExpectedValue(expectedMessage);
    }
    public override void WriteActualValueTo(MessageWriter writer)
    {
        writer.WriteExpectedValue(actualMessage);
    }
}

প্লাস হেল্পার ক্লাস:

public static class PortfolioState
{
    public static PortfolioEqualityConstraint Matches(Portfolio expected)
    {
        return new PortfolioEqualityConstraint(expected);
    }

    public static string ToStringForTest(this Portfolio source)
    {
        return String.Format("Property1 = {0}, Property2 = {1}, Property3 = {2}.", 
            source.Property1, source.Property2, source.Property3 );
    }
}

ব্যবহারের উদাহরণ:

[TestFixture]
class PortfolioTests
{
    [Test]
    public void TestPortfolioEquality()
    {
        Portfolio LeftObject 
            = Portfolio.GetDefault();
        Portfolio RightObject 
            = Portfolio.GetPortfolio("{{GNOME}}", "{{NONE}}", "{{NONE}}");

        Assert.That( LeftObject, PortfolioState.Matches( RightObject ) );
    }
}

1

আমি @ জুয়ানমার উত্তরে তৈরি করব। যাইহোক, আমি বিশ্বাস করি এটি ইউনিট পরীক্ষার দাবিগুলির সাথে বাস্তবায়ন করা উচিত নয়। এটি এমন একটি ইউটিলিটি যা কিছু পরিস্থিতিতে টেস্টবিহীন কোড দ্বারা খুব ভালভাবে ব্যবহার করা যেতে পারে।

আমি এই বিষয়ে একটি নিবন্ধ লিখেছিলাম http://timoch.com/blog/2013/06/unit-test-equality-is-not-domain-equality/

আমার প্রস্তাবটি নিম্নরূপ:

/// <summary>
/// Returns the names of the properties that are not equal on a and b.
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns>An array of names of properties with distinct 
///          values or null if a and b are null or not of the same type
/// </returns>
public static string[] GetDistinctProperties(object a, object b) {
    if (object.ReferenceEquals(a, b))
        return null;
    if (a == null)
        return null;
    if (b == null)
        return null;

    var aType = a.GetType();
    var bType = b.GetType();

    if (aType != bType)
        return null;

    var props = aType.GetProperties();

    if (props.Any(prop => prop.GetIndexParameters().Length != 0))
        throw new ArgumentException("Types with index properties not supported");

    return props
        .Where(prop => !Equals(prop.GetValue(a, null), prop.GetValue(b, null)))
        .Select(prop => prop.Name).ToArray();
} 

নুনিটের সাথে এটি ব্যবহার করা

Expect(ReflectionUtils.GetDistinctProperties(tile, got), Empty);

অমিলের উপর নিম্নলিখিত বার্তা দেয়।

Expected: <empty>
But was:  < "MagmaLevel" >
at NUnit.Framework.Assert.That(Object actual, IResolveConstraint expression, String message, Object[] args)
at Undermine.Engine.Tests.TileMaps.BasicTileMapTests.BasicOperations() in BasicTileMapTests.cs: line 29

1

https://github.com/kbilsted/StatePrinter বিশেষ ইউনিট পরীক্ষা লেখার লক্ষ্য নিয়ে স্ট্রিং উপস্থাপনায় অবজেক্ট গ্রাফগুলি ডাম্প করার জন্য বিশেষভাবে লেখা হয়েছে।

  • এটি আসল বিস্ময়কর পদ্ধতিগুলি যা পরীক্ষার জন্য সঠিকভাবে পালানো স্ট্রিং সহজ কপি-পেস্টকে আউটপুট দেয় এটি সংশোধন করে।
  • এটি ইউনিটেস্টকে স্বয়ংক্রিয়ভাবে পুনরায় লেখার অনুমতি দেয়
  • এটি সমস্ত ইউনিট টেস্টিং ফ্রেমওয়ার্কের সাথে সংহত করে
  • জেএসওএন সিরিয়ালাইজের বিপরীতে, বিজ্ঞপ্তি উল্লেখগুলি সমর্থিত are
  • আপনি সহজেই ফিল্টার করতে পারেন, সুতরাং কেবলমাত্র ধরণের অংশগুলি ডাম্প করা হয়

প্রদত্ত

class A
{
  public DateTime X;
  public DateTime Y { get; set; }
  public string Name;
}

আপনি কোনও প্রকার নিরাপদ উপায়ে, এবং ভিজ্যুয়াল স্টুডিওর স্বয়ংক্রিয়ভাবে সমাপ্তি ব্যবহারের সাথে ক্ষেত্রগুলি অন্তর্ভুক্ত বা বাদ দিতে পারেন।

  var printer = new Stateprinter();
  printer.Configuration.Projectionharvester().Exclude<A>(x => x.X, x => x.Y);

  var sut = new A { X = DateTime.Now, Name = "Charly" };

  var expected = @"new A(){ Name = ""Charly""}";
  printer.Assert.PrintIsSame(expected, sut);

1

নুগেট থেকে কেবল এক্সপেক্টেডঅবজেক্টগুলি ইনস্টল করুন, আপনি সহজেই দুটি অবজেক্টের সম্পত্তি মান, সংগ্রহের প্রতিটি বস্তুর মান, দুটি রচিত বস্তুর মান এবং আংশিক তুলনা করতে পারেন বেনামে প্রকারের দ্বারা সম্পত্তি মান।

গিথুব সম্পর্কে আমার কয়েকটি উদাহরণ রয়েছে: https://github.com/hatelove/CompareObjectEquals

এখানে কিছু উদাহরণ রয়েছে যা তুলনামূলক অবজেক্টের দৃশ্য ধারণ করে:

    [TestMethod]
    public void Test_Person_Equals_with_ExpectedObjects()
    {
        //use extension method ToExpectedObject() from using ExpectedObjects namespace to project Person to ExpectedObject
        var expected = new Person
        {
            Id = 1,
            Name = "A",
            Age = 10,
        }.ToExpectedObject();

        var actual = new Person
        {
            Id = 1,
            Name = "A",
            Age = 10,
        };

        //use ShouldEqual to compare expected and actual instance, if they are not equal, it will throw a System.Exception and its message includes what properties were not match our expectation.
        expected.ShouldEqual(actual);
    }

    [TestMethod]
    public void Test_PersonCollection_Equals_with_ExpectedObjects()
    {
        //collection just invoke extension method: ToExpectedObject() to project Collection<Person> to ExpectedObject too
        var expected = new List<Person>
        {
            new Person { Id=1, Name="A",Age=10},
            new Person { Id=2, Name="B",Age=20},
            new Person { Id=3, Name="C",Age=30},
        }.ToExpectedObject();

        var actual = new List<Person>
        {
            new Person { Id=1, Name="A",Age=10},
            new Person { Id=2, Name="B",Age=20},
            new Person { Id=3, Name="C",Age=30},
        };

        expected.ShouldEqual(actual);
    }

    [TestMethod]
    public void Test_ComposedPerson_Equals_with_ExpectedObjects()
    {
        //ExpectedObject will compare each value of property recursively, so composed type also simply compare equals.
        var expected = new Person
        {
            Id = 1,
            Name = "A",
            Age = 10,
            Order = new Order { Id = 91, Price = 910 },
        }.ToExpectedObject();

        var actual = new Person
        {
            Id = 1,
            Name = "A",
            Age = 10,
            Order = new Order { Id = 91, Price = 910 },
        };

        expected.ShouldEqual(actual);
    }

    [TestMethod]
    public void Test_PartialCompare_Person_Equals_with_ExpectedObjects()
    {
        //when partial comparing, you need to use anonymous type too. Because only anonymous type can dynamic define only a few properties should be assign.
        var expected = new
        {
            Id = 1,
            Age = 10,
            Order = new { Id = 91 }, // composed type should be used anonymous type too, only compare properties. If you trace ExpectedObjects's source code, you will find it invoke config.IgnoreType() first.
        }.ToExpectedObject();

        var actual = new Person
        {
            Id = 1,
            Name = "B",
            Age = 10,
            Order = new Order { Id = 91, Price = 910 },
        };

        // partial comparing use ShouldMatch(), rather than ShouldEqual()
        expected.ShouldMatch(actual);
    }

রেফারেন্স:

  1. প্রত্যাশিত অবজেক্টস গিথুব
  2. প্রত্যাশিত অবজেক্টস পরিচিতি


1

আমি একটি সাধারণ এক্সপ্রেশন কারখানা লিখে শেষ করেছি:

public static class AllFieldsEqualityComprision<T>
{
    public static Comparison<T> Instance { get; } = GetInstance();

    private static Comparison<T> GetInstance()
    {
        var type = typeof(T);
        ParameterExpression[] parameters =
        {
            Expression.Parameter(type, "x"),
            Expression.Parameter(type, "y")
        };
        var result = type.GetProperties().Aggregate<PropertyInfo, Expression>(
            Expression.Constant(true),
            (acc, prop) =>
                Expression.And(acc,
                    Expression.Equal(
                        Expression.Property(parameters[0], prop.Name),
                        Expression.Property(parameters[1], prop.Name))));
        var areEqualExpression = Expression.Condition(result, Expression.Constant(0), Expression.Constant(1));
        return Expression.Lambda<Comparison<T>>(areEqualExpression, parameters).Compile();
    }
}

এবং কেবল এটি ব্যবহার করুন:

Assert.That(
    expectedCollection, 
    Is.EqualTo(actualCollection)
      .Using(AllFieldsEqualityComprision<BusinessCategoryResponse>.Instance));

এটি খুব দরকারী যেহেতু আমাকে এ জাতীয় অবজেক্টগুলির সংগ্রহের তুলনা করতে হবে। এবং আপনি এই তুলনামূলক অন্য কোথাও ব্যবহার করতে পারেন :)

এখানে উদাহরণ সহকারে বলা হয়েছে: https://gist.github.com/Pzix/b63fea074864892f9aba8ffde312094f


0

উভয় শ্রেণীর ডিয়েসরিয়াল করুন এবং একটি স্ট্রিং তুলনা করুন।

সম্পাদনা: নিখুঁতভাবে কাজ করে, এটি আমি ইউএনজিট থেকে প্রাপ্ত আউটপুট;

Test 'Telecom.SDP.SBO.App.Customer.Translator.UnitTests.TranslateEaiCustomerToDomain_Tests.TranslateNew_GivenEaiCustomer_ShouldTranslateToDomainCustomer_Test("ApprovedRatingInDb")' failed:
  Expected string length 2841 but was 5034. Strings differ at index 443.
  Expected: "...taClasses" />\r\n  <ContactMedia />\r\n  <Party i:nil="true" /..."
  But was:  "...taClasses" />\r\n  <ContactMedia>\r\n    <ContactMedium z:Id="..."
  ----------------------------------------------^
 TranslateEaiCustomerToDomain_Tests.cs(201,0): at Telecom.SDP.SBO.App.Customer.Translator.UnitTests.TranslateEaiCustomerToDomain_Tests.Assert_CustomersAreEqual(Customer expectedCustomer, Customer actualCustomer)
 TranslateEaiCustomerToDomain_Tests.cs(114,0): at Telecom.SDP.SBO.App.Customer.Translator.UnitTests.TranslateEaiCustomerToDomain_Tests.TranslateNew_GivenEaiCustomer_ShouldTranslateToDomainCustomer_Test(String custRatingScenario)

সম্পাদনা করুন দুটি: দুটি বস্তু একরকম হতে পারে, তবে বৈশিষ্ট্যগুলি ক্রমিকভাবে ক্রমিক করা একই নয়। সুতরাং এক্সএমএল পৃথক is DOH এর!

তিনটি সম্পাদনা করুন: এটি কাজ করে। আমি আমার পরীক্ষায় এটি ব্যবহার করছি। কিন্তু পরীক্ষার কোডটি সেটিকে যুক্ত করে ক্রমে আপনার অবশ্যই সংগ্রহের বৈশিষ্ট্যে আইটেম যুক্ত করতে হবে।


1
সিরিয়াল করবেন ? আকর্ষণীয় ধারণা। পারফরম্যান্সের ক্ষেত্রে এটি কীভাবে ধরে রাখবে তা আমি নিশ্চিত নই, যদিও
মাইকেল হরেন

আপনাকে প্রদত্ত যথার্থতার সাথে ডাবল বা দশমিকের তুলনা করতে দেবে না।
Noctis

0

আমি জানি এটি একটি সত্যই পুরানো প্রশ্ন, তবে ইউনিতের এখনও এর পক্ষে স্থানীয় সমর্থন নেই। তবে, আপনি যদি বিডিডি-শৈলীর পরীক্ষা পছন্দ করেন (আলা জেসমিন), আপনি NExpect ( https://github.com/fluffynuts/NExpect , এটি নিউগেট থেকে পান) নিয়ে আনন্দিতভাবে অবাক হবেন , যেখানে গভীর সমতা পরীক্ষা রয়েছে ঠিক সেখানেই ।

(অস্বীকৃতি: আমি এনএক্সপ্যাক্টের লেখক)


-1

দুটি স্ট্রিংকে স্ট্রিংফাই করে তুলনা করুন

Assert.AreEqual (JSON.stringify (LeftObject), JSON.stringify (রাইটওজেক্ট))


-1
//Below works precisely well, Use it.
private void CompareJson()
{
object expected = new object();
object actual = new object();
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
var expectedResponse = serializer.Serialize(expected);
var actualResponse = serializer.Serialize(actual);
Assert.AreEqual(expectedResponse, actualResponse);
}

এই কোড স্নিপেটের জন্য আপনাকে ধন্যবাদ, যা কিছু সীমিত স্বল্পমেয়াদী সহায়তা সরবরাহ করতে পারে। একটি সঠিক ব্যাখ্যা কেন এটি সমস্যার একটি ভাল সমাধান তা দেখিয়ে তার দীর্ঘমেয়াদী মানকে ব্যাপকভাবে উন্নত করবে এবং ভবিষ্যতে পাঠকদের আরও অন্যান্য অনুরূপ প্রশ্নের সাথে আরও দরকারী করে তুলবে। আপনার অনুমানগুলি সহ কিছু ব্যাখ্যা যুক্ত করতে দয়া করে আপনার উত্তরটি সম্পাদনা করুন।
টবি স্পিড 12

এবং এটি ম্যাক্সের উত্তরে কী যুক্ত করে?
টবি স্পিড 12
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.