হার্ড কোডেড অবজেক্টের সাথে কীভাবে মক পদ্ধতিটি?


11

আমি এমন একটি অ্যাপ্লিকেশন নিয়ে কাজ করছি যার একাধিক স্তর রয়েছে। ডেটা উত্স থেকে ডেটা পুনরুদ্ধার এবং সংরক্ষণের জন্য ডেটা অ্যাক্সেস লেয়ার, ডেটা ম্যানিপুলেট করতে ব্যবসায়ের লজিক, স্ক্রিনে ডেটা প্রদর্শনের জন্য ইউজার ইন্টারফেস।

আমি ব্যবসার লজিক স্তরটির ইউনিট টেস্টিংও করছি। একমাত্র প্রয়োজন হ'ল ব্যবসায়ের স্তর যুক্তির প্রবাহ পরীক্ষা করা। সুতরাং আমি ডেটা অ্যাক্সেস লেয়ারকে উপহাস করার জন্য ম্যাক ফ্রেমওয়ার্ক ব্যবহার করি এবং এমএস ইউনিটের সাথে ইউনিটটি ব্যবসায়ের লজিক স্তরটি পরীক্ষা করি।

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

আমি যখন ব্যবসার লজিক পদ্ধতির একটি পরীক্ষা করার চেষ্টা করছি তখন আমি সমস্যার মুখোমুখি হয়েছি। এই পদ্ধতিটি কিছু কাজ করে এবং একটি অবজেক্ট তৈরি করে ডেটা অ্যাক্সেস লেয়ারে দেয় pass যখন আমি সেই ডেটা অ্যাক্সেস স্তর পদ্ধতিটি উপহাস করার চেষ্টা করছি তখন এটি সফলভাবে বিদ্রূপ করতে পারে না।

এখানে আমি আমার সমস্যাটি দেখানোর জন্য একটি ডেমো কোড তৈরি করার চেষ্টা করছি।

মডেল:

public class Employee
{
    public string Name { get; set; }
}

ডেটা অ্যাক্সেস স্তর:

public interface IDal
{
    string GetMessage(Employee emp);
}

public class Dal : IDal
{
    public string GetMessage(Employee emp)
    {
        // Doing some data source access work...

        return string.Format("Hello {0}", emp.Name);
    }
}

ব্যবসায় যুক্তিযুক্ত স্তর:

public interface IBll
{
    string GetMessage();
}

public class Bll : IBll
{
    private readonly IDal _dal;

    public Bll(IDal dal)
    {
        _dal = dal;
    }

    public string GetMessage()
    {
        // Object creating inside business logic method.
        Employee emp = new Employee(); 

        string msg = _dal.GetMessage(emp);
        return msg;
    }
}

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

[TestMethod]
    public void Is_GetMessage_Return_Proper_Result()
    {
        // Arrange.
        Employee emp = new Employee; // New object.

        Mock<IDal> mockDal = new Mock<IDal>();
        mockDal.Setup(d => d.GetMessage(emp)).Returns("Hello " + emp.Name);

        IBll bll = new Bll(mockDal.Object);

        // Act.

        // This will create another employee object inside the 
        // business logic method, which is different from the 
        // object which I have sent at the time of mocking.
        string msg = bll.GetMessage(); 

        // Assert.
        Assert.AreEqual("Hello arnab", msg);
    }

বিদ্রূপ করার সময় ইউনিট পরীক্ষার ক্ষেত্রে আমি একজন কর্মচারী বস্তু পাঠাচ্ছি তবে ব্যবসায়ের যুক্তি পদ্ধতিটি যখন প্রবর্তন করা হয় তখন এটি পদ্ধতির অভ্যন্তরে বিভিন্ন কর্মচারী বস্তু তৈরি করছে। এজন্য আমি বস্তুটিকে উপহাস করতে পারি না।

সেক্ষেত্রে কীভাবে ডিজাইন করব যাতে আমি সমস্যার সমাধান করতে পারি?


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

উত্তর:


12

Employeeসরাসরি ব্যবহার করে কোনও অবজেক্ট তৈরি করার পরিবর্তে new, আপনার শ্রেণি এটির জন্য একটি পদ্ধতি Bllব্যবহার করতে পারে EmployeeFactory, এমন একটি পদ্ধতি createInstanceযা নির্মাণকারীর মাধ্যমে ইঞ্জেক্ট করা হয়:

 class EmployeeFactory : IEmployeeFactory
 {
       public Employee createInstance(){return new Employee();}
 }

কনস্ট্রাক্টরের উচিত ইন্টারফেসের মাধ্যমে কারখানার অবজেক্টটি নেওয়া IEmployeeFactory, যাতে আপনি একটি "মোকদ্দমা" তৈরির কারখানা দ্বারা সহজেই এটি "রিয়েল" কারখানাটি প্রতিস্থাপন করতে পারেন।

public class Bll : IBll
{
    private readonly IDal _dal;
    private readonly IEmployeeFactory _employeeFactory;

    public Bll(IDal dal, IEmployeeFactory employeeFactory)
    {
        _dal = dal;
        _employeeFactory=employeeFactory;
    }

    public string GetMessage()
    {
        // Object creating inside business logic method
        // *** using a factory ***
        Employee emp = _employeeFactory.createObject(); 
        // ...
    }
    //...
}

মক ফ্যাক্টরি Employeeআপনার পরীক্ষার জন্য যে কোনও ধরণের অবজেক্টের প্রয়োজন যা পরীক্ষা সরবরাহ createInstanceকরতে পারে (উদাহরণস্বরূপ, সর্বদা একই জিনিসটি ফেরত দিতে পারে):

 class MockEmployeeFactory : IEmployeeFactory
 {
       private Employee _emp;

       public MockEmployeeFactory()
       {
          _emp = new Employee();
          // add any kind of special initializing here for testing purposes
       }

       public Employee createInstance()
       {
          // just for testing, return always the same object
          return _emp;
       }
 }

এখন আপনার পরীক্ষায় এই মক ব্যবহার করা কৌশলটি করা উচিত।


আপনি কি আমাকে একটি কোড উদাহরণ দিতে পারেন, যাতে আমি আপনার তত্ত্বটি কল্পনা করতে পারি?
বিকাশকারী

@ ডেভেলপারআরনাব: আমার সম্পাদনা দেখুন।
ডক ব্রাউন

খুব সহায়ক ...
বিকাশকারী

4

আমি এটি পরীক্ষার জন্য একক ইউনিট হিসাবে বিবেচনা করব।

যতক্ষণ আপনি সমস্ত ইনপুটগুলি নিয়ন্ত্রণ করেন যা থেকে Employeeঅবজেক্টটি তৈরি করা হয় ততক্ষণ পরীক্ষিত অবজেক্টে এটি তৈরি হওয়ার বিষয়টি বিবেচ্য নয়। যদি তর্কের বিষয়বস্তু প্রত্যাশার সাথে মেলে তবে আপনার প্রত্যাশিত ফলাফলটি ফেরত দেওয়ার জন্য কেবল একটি মক পদ্ধতি দরকার।

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

প্রকৃতপক্ষে, পরীক্ষাগুলিতে এটি উত্পাদন হওয়ার চেয়ে আলাদা আলাদা বস্তুটিকে ফিরিয়ে দেওয়া উচিত নয় , কারণ যদি আপনি এটি করেন তবে আপনি কোডটি তৈরি করবেন না যা এটি তৈরি করা উচিত। তবে সেই কোডটি উত্পাদন কোডের অবিচ্ছেদ্য অঙ্গ এবং তাই পরীক্ষার ক্ষেত্রেও এটি আচ্ছাদিত করা উচিত।


হ্যাঁ, আমি ডেটা অ্যাক্সেস লেয়ারের ইনপুটগুলি নিয়ে মাথা ঘামাই না, আমি কেবল সেই বিষয়টিকে উপহাস করতে চাই এবং একটি হার্ড কোডিং ডেটা ফিরিয়ে দিতে চাই যাতে আমি ব্যবসায়ের যুক্তি পরীক্ষা করতে পারি। তবে সমস্যাটি হ'ল দুটি পৃথক কর্মচারী বস্তুর কারণে, আমি ডেটা অ্যাক্সেস স্তর পদ্ধতিটি উপহাস করতে পারি না।
বিকাশকারী

@ ডেভেলপারআরনাব: বস্তুগুলি পৃথক হবে তবে তাদের জ্ঞাত সামগ্রী থাকবে। সুতরাং আপনাকে যা করতে হবে তা হ'ল বস্তু পরিচয়ের পরিবর্তে মোককে কাস্টম তুলনা করা।
জানু হুডেক

@ ডেভেলপারআরনাব: আপনি যদি Employeeপরীক্ষাগুলিতে পৃথক অবজেক্টটি ইনজেক্ট করেন তবে আপনি যে কোডটি সাধারণত এটি তৈরি করেন তা পরীক্ষা করবেন না। সুতরাং আপনি এটি পরিবর্তন করা উচিত নয়।
জানু হুডেক

0

এটি কিছু পরীক্ষার সরঞ্জামগুলির ব্যর্থতা, আপনাকে সর্বদা ইন্টারফেস ব্যবহার করতে হবে এবং সমস্ত কিছু এমনভাবে তৈরি করতে হবে যা আপনাকে অন্য একটিটির জন্য ইন্টারফেস ভিত্তিক অবজেক্টকে সরিয়ে নিতে দেয়।

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

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