আমি কীভাবে Assert ব্যবহার করব? ব্যতিক্রমের ধরণটি সংযোজন করতে চেষ্টা করুন?


247

আমি কীভাবে Assert.Throwsব্যতিক্রমের ধরণ এবং প্রকৃত বার্তা শব্দভাজন যুক্ত করতে ব্যবহার করব।

এটার মতো কিছু:

Assert.Throws<Exception>(
    ()=>user.MakeUserActive()).WithMessage("Actual exception message")

আমি যে পদ্ধতিটি পরীক্ষা করছি তা বিভিন্ন বার্তার সাথে একই ধরণের একাধিক বার্তা ছুড়ে ফেলেছে এবং প্রসঙ্গের উপর নির্ভর করে সঠিক বার্তাটি নিক্ষেপ করা হয়েছে তা পরীক্ষা করার জন্য আমার একটি উপায় প্রয়োজন।

উত্তর:


444

Assert.Throws ফেলে দেওয়া ব্যতিক্রমটি ফিরিয়ে দেয় যা আপনাকে ব্যতিক্রম দৃ as় করতে দেয়।

var ex = Assert.Throws<Exception>(() => user.MakeUserActive());
Assert.That(ex.Message, Is.EqualTo("Actual exception message"));

সুতরাং যদি কোনও ব্যতিক্রম নিক্ষেপ করা হয় না, বা ভুল ধরণের একটি ব্যতিক্রম নিক্ষেপ করা হয় তবে প্রথম Assert.Throwsদৃser়তা ব্যর্থ হবে। তবে যদি সঠিক ধরণের একটি ব্যতিক্রম ছুঁড়ে দেওয়া হয় তবে আপনি এখন আসল ব্যতিক্রমটি দৃ saved়ভাবে বলতে পারবেন যে আপনি ভেরিয়েবলে সংরক্ষণ করেছেন।

এই প্যাটার্নটি ব্যবহার করে আপনি ব্যতিক্রম বার্তাগুলি বাদ দিয়ে অন্য কিছুতে দৃsert়তা রাখতে পারেন, উদাহরণস্বরূপ ArgumentExceptionএবং ডেরিভেটিভসের ক্ষেত্রে , আপনি জোর দিয়ে বলতে পারেন যে প্যারামিটারের নামটি সঠিক:

var ex = Assert.Throws<ArgumentNullException>(() => foo.Bar(null));
Assert.That(ex.ParamName, Is.EqualTo("bar"));

আপনি এই দৃser়তাগুলি করার জন্য সাবলীল এপিআইও ব্যবহার করতে পারেন:

Assert.That(() => foo.Bar(null), 
Throws.Exception
  .TypeOf<ArgumentNullException>()
  .With.Property("ParamName")
  .EqualTo("bar"));

বা বিকল্পভাবে

Assert.That(
    Assert.Throws<ArgumentNullException>(() =>
        foo.Bar(null)
    .ParamName,
Is.EqualTo("bar"));

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


এটি আমার জন্য সত্যই সহায়ক ছিল - আমি ত্রুটিটি প্রদর্শন করার জন্য একটি উপায় চাইছিলাম, আমি এমনকি লিখতে পারি না যদি কোনও মান সঞ্চারিত হয়। ধন্যবাদ
হারুন

6
+1 ফ্লুয়েন্ট এপিআই দেখানোর জন্য আপনাকে ধন্যবাদ, কিছু কারণের জন্য আমি কেবল নুনিট ডকুমেন্ট থেকে এটি কীভাবে ব্যবহার করতে পারি তা বুঝতে আমার সমস্যা হয়েছিল।
আওলসোওকা

আপনি যখন বার্তাটি জোড় করতে চান, আপনি সরাসরি "সম্পত্তি" এর পরিবর্তে বার্তা বৈশিষ্ট্যটিও ব্যবহার করতে পারেন।
মার্সেল

25

আপনি এখন ExpectedExceptionবৈশিষ্ট্যগুলি ব্যবহার করতে পারেন , যেমন

[Test]
[ExpectedException(typeof(InvalidOperationException), 
 ExpectedMessage="You can't do that!"]
public void MethodA_WithNull_ThrowsInvalidOperationException()
{
    MethodA(null);
}

2
এটি প্রথম দেখার সময় আমাকে কিছুটা বিরক্ত করেছিল, কারণ পরীক্ষার আপেলের কোনও দাবি ছিল না, যা আমার কাছে গন্ধযুক্ত ছিল। এটি একটি দুর্দান্ত বৈশিষ্ট্য, তবে এই বৈশিষ্ট্যটি অ্যাসেসর্টের উপরে ব্যবহার করা উচিত, এমন দলে যে কোনও বিষয়ে আলোচনা করা উচিত hআপনি
মার্সেল

14
ব্যতিক্রমগুলির জন্য পরীক্ষার একটি দুর্দান্ত উপায় +1। এই বিষয়টি মনে রাখার একমাত্র বিষয়টি তাত্ত্বিকভাবে যে বার্তাটি দিয়ে একটি অবৈধ অপ্রকাশের ধারণা ছুঁড়ে দেওয়া কোডের কোনও লাইনই পরীক্ষায় পাস করবে, আপনার পরীক্ষার কোড সহ যা পরীক্ষার ডেটা / অবজেক্টগুলি প্রস্তুত করে বা অন্য যে কোনও পদ্ধতিতে আপনাকে কার্যকর করার আগে প্রয়োজন হতে পারে আপনি যা পরীক্ষা করতে আগ্রহী তা সম্ভবত ফলস ধনাত্মক হতে পারে। অবশ্যই, এটি নির্ভর করে বার্তাটি কতটা সুনির্দিষ্ট এবং আপনি কীভাবে ব্যতিক্রম পরীক্ষা করছেন। সঙ্গে Assert.Throwআপনি সঠিক লাইন লক্ষ্য করতে পারেন আপনি আগ্রহী।
নাঃ


13
Assert.That(myTestDelegate, Throws.ArgumentException
    .With.Property("Message").EqualTo("your argument is invalid."));

2
নাম অপারেটরের সাথে পরিচয় করিয়ে দিয়ে আমি এই চমৎকার আনসারটি সম্পাদনা করব:Assert.That(myTestDelegate, Throws.ArgumentException .With.Property(nameof(ArgumentException.Message)).EqualTo("your argument is invalid."));
স্যামুয়েল

@ সামুয়েল এই সম্পাদনাটিতে দৃ strongly়ভাবে টাইপ করা রেফারেন্স ব্যবহার করা হবে যা দুর্দান্ত, তবে অন্যদিকে এটি অত্যন্ত স্বল্প পরিমাণে সম্পত্তি নাম এবং ম্যাজিক স্ট্রিংয়ের স্বাদকে উন্নত করে। স্বাদের বিষয় হিসাবে আমি মনে করি
জর্ডান মরিস

1
আমি সম্পূর্ণরূপে আপনার সাথে একমত Exception.Message। আমি এখনও অন্তত এই বিকল্পটি যুক্ত করার পরামর্শ দেব কারণ With.Propertyঅন্যান্য বস্তুগুলিতেও এটি ব্যবহার করা যেতে পারে, যা এই ক্ষেত্রে কোডের স্থায়িত্বের উন্নতি করবে।
স্যামুয়েল

5

পুরানো উত্তর সহ এটি একটি পুরানো তবে প্রাসঙ্গিক প্রশ্ন তাই আমি বর্তমান সমাধানটি যুক্ত করছি:

public void Test() {
    throw new MyCustomException("You can't do that!");
}

[TestMethod]
public void ThisWillPassIfExceptionThrown()
{
    var exception = Assert.ThrowsException<MyCustomException>(
        () => Test(),
        "This should have thrown!");
    Assert.AreEqual("You can't do that!", exception.Message);
}

এটি দিয়ে কাজ করে using Microsoft.VisualStudio.TestTools.UnitTesting;


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

3

অবিরামের উত্তরটি প্রসারিত করতে এবং NUnit এর কার্যকারিতা আরও সরবরাহ করতে আপনি এটি করতে পারেন:

public bool AssertThrows<TException>(
    Action action,
    Func<TException, bool> exceptionCondition = null)
    where TException : Exception 
{
    try
    {
        action();
    }
    catch (TException ex)
    {
        if (exceptionCondition != null)
        {
            return exceptionCondition(ex);
        }

        return true;
    }
    catch
    {
        return false;
    }

    return false; 
}

উদাহরণ:

// No exception thrown - test fails.
Assert.IsTrue(
    AssertThrows<InvalidOperationException>(
        () => {}));

// Wrong exception thrown - test fails.
Assert.IsTrue(
    AssertThrows<InvalidOperationException>(
        () => { throw new ApplicationException(); }));

// Correct exception thrown - test passes.
Assert.IsTrue(
    AssertThrows<InvalidOperationException>(
        () => { throw new InvalidOperationException(); }));

// Correct exception thrown, but wrong message - test fails.
Assert.IsTrue(
    AssertThrows<InvalidOperationException>(
        () => { throw new InvalidOperationException("ABCD"); },
        ex => ex.Message == "1234"));

// Correct exception thrown, with correct message - test passes.
Assert.IsTrue(
    AssertThrows<InvalidOperationException>(
        () => { throw new InvalidOperationException("1234"); },
        ex => ex.Message == "1234"));

2

এই বিষয়টি উত্থাপিত হওয়ার অনেক দিন পরে, আমি বুঝতে পেরেছি, তবে আমি সম্প্রতি একই জিনিসটিতে চলেছি এবং এমএসটিস্টের জন্য এই ফাংশনটির পরামর্শ দিচ্ছি:

public bool AssertThrows(Action action) where T : Exception 
{ 
try {action();} 
catch(Exception exception) 
{ 
    if (exception.GetType() == typeof(T)) return true; 
} 
return false; 
}

ব্যবহার:

Assert.IsTrue(AssertThrows<FormatException>(delegate{ newMyMethod(MyParameter); }));

আরও এখানে: http://phejndorf.wordpress.com/2011/02/21/assert-that-a-particular-exception-has-occured/


2

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

public void AssertBusinessRuleException(TestDelegate code, string expectedMessage)
{
    var ex = Assert.Throws<BusinessRuleException>(code);
    Assert.AreEqual(ex.Message, expectedMessage);
}

public void AssertException<T>(TestDelegate code, string expectedMessage) where T:Exception
{
    var ex = Assert.Throws<T>(code);
    Assert.AreEqual(ex.Message, expectedMessage);
}

ব্যবহারটি তখন হয়:

AssertBusinessRuleException(() => user.MakeUserActive(), "Actual exception message");

1
টেস্টডেলিগেট কী?
রেগেইগুইটার

1
এটি আপনাকে প্যারামিটার হিসাবে কার্যকর করতে কোডটি পাস করার অনুমতি দেয়। এটি NUnit কাঠামোর (v3.2.0.0) শ্রেণি।
সেভেজ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.