মক: একটি অ-ওভারডেবল সদস্যের জন্য অবৈধ সেটআপ: x => x. গেটবাইটিল ("এসএসডিএফ")


111

"GetByTitle" পদ্ধতিতে ইউনিট পরীক্ষা করার চেষ্টা করে আমি কীভাবে এটি ঠিক করতে পারি তা নিশ্চিত নই

এখানে আমার সংজ্ঞা রয়েছে:

public class ArticleDAO :  GenericNHibernateDAO(IArticle, int>, IArticleDAO
{
    public IArticle GetByTitle(string title)
    {
        IQuery query = Session.CreateQuery("...")
        return query.UniqueResult<IArticle>();
    }
}

public interface IArticleDAO
{
    IArticle GetByTitle(string title);
}

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

[Test]
public void can_load_by_title()
{
    _mockDaoFactory.Setup(x => x.GetArticleDao())
                                .Returns(_mockArticleDao.Object);
    _mockArticleDao.Setup(x => x.GetByTitle("some title"))
                                .Returns(article1.Object);

    _articleManager.LoadArticle("some title");

    Assert.IsNotNull(_articleManager.Article);
}

পরীক্ষা চালানো আমাকে ত্রুটি দেয়:

System.ArgumentException: Invalid setup on a non-overridable member:
x => x.GetByTitle("some title")

হালনাগাদ

আমার [Setup]দেখতে দেখতে:

[Setup]
public void SetUp()
{
     _mockDaoFactory = new Mock<IDaoFactory>();
     _mockArticleDao = new Mock<ArticleDao>();

     _articleManager = new ArticleManager(_mockDaoFactory.Object);    
}

2
আপনি instantiate না _mockDaoFactoryএবং _mockArticleDaoকোথাও? আপনি কি ক্লাস বা ইন্টারফেসকে উপহাস করছেন
টমাস আসচান

হ্যাঁ আমি ইন্টারফেসটি ব্যবহার করে [সেটআপ] এ দাওফ্যাক্টরি এবং মকনারিক্যালডাওকে উপহাস করেছি। ডিএও ক্লাসটি ব্যবহার করে করা হয়েছিল।
mrblah

@ টমাস আমি সেটআপ কোড দিয়ে আমার প্রশ্ন আপডেট করেছি।
mrblah

2
আপনি আমার উত্তরে দেখতে পাচ্ছেন, আপনাকে ইন্টারফেসটি উপহাস করতে হবে (এটি আমি প্রস্তাবিত) বা GetByTitleপদ্ধতিটি চিহ্নিত করতে হবে virtual
টমাস আসচান

দেখে মনে হচ্ছে আপনার পরীক্ষার প্রথম লাইনটি সেটআপ রুটিনে সরানো যেতে পারে ...?
টমাস আসচান

উত্তর:


154

একটি মক অবজেক্টের আচরণ নিয়ন্ত্রণের জন্য (মোকে, কমপক্ষে) আপনার অবশ্যই একটি ইন্টারফেসকে উপহাস করা উচিত, অথবা আপনি যে আচরণটি নিয়ন্ত্রণের চেষ্টা করছেন সেটি ভার্চুয়াল হিসাবে চিহ্নিত হয়েছে কিনা তা নিশ্চিত হওয়া উচিত। আপনার মন্তব্যে, আমি এটি বুঝতে পেরেছি যাতে তাত্ক্ষণিকভাবে কিছু করা _mockArticleDaoহয়:

_mockArticleDao = new Mock<ArticleDAO>();

আপনি যদি এটি ঠিক রাখতে চান তবে আপনার GetArticleপদ্ধতিটি চিহ্নিত করতে হবে virtual:

public class ArticleDAO :  GenericNHibernateDAO(IArticle, int>, IArticleDAO
{
    public virtual IArticle GetByTitle(string title)
    {
        // ...
    }
}

অন্যথায় (এবং এটিই আমি প্রস্তাব করি), পরিবর্তে ইন্টারফেসটি উপহাস করুন।

_mockArticleDao = new Mock<IArticleDAO>();

তবে যেহেতু ArticleDOO জেনেরিকের কাছ থেকে উত্তরাধিকার সূত্রে প্রাপ্ত ...., যদি আমি জেনেরিকনবার্নের পদ্ধতিগুলিকে ইন্টারফেসটি উপহাস করি। উপলব্ধ করা হবে না?
mrblah

কারখানা থেকে গেটআর্টিকেলডিও-তে কল আইআর্টিকেলডিও নয়, আর্টিকেল ডিও প্রদান করে, খ / সি নিবন্ধ ডিওও একটি বিমূর্ত শ্রেণীর সাথে আবদ্ধ হয় যাতে এতে নিবার্ট স্টাফ থাকে।
mrblah

2
আপনি যদি ইন্টারফেসটিকে উপহাস করতে না পারেন, তবে আপনি হয়ত ভুল জিনিসটি পরীক্ষা করছেন ... তবে তবুও, পদ্ধতিটি ভার্চুয়াল চিহ্নিতকরণ সমস্যার সমাধান করবে।
টমাস আসচান

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

4
@ কাভ: আপনার যদি কনস্ট্রাক্টরতে কিছু ইনজেকশন লাগানোর দরকার হয় তবে আপনি অবশ্যই ভুল জিনিসটি পরীক্ষা করছেন। আপনি কনস্ট্রাক্টরকে যা কিছু দেবেন তা উপহাস করুন, এটির আচরণটি সেটআপ করুন এবং পরীক্ষা করুন যে এই শ্রেণিটি যেমন করা উচিত তেমন আচরণ করে। আপনার যদি প্রয়োজন হয় তবে একটি নতুন ইন্টারফেস লিখুন যা আপনি সমস্ত পদ্ধতি স্বাক্ষর অ্যাক্সেস করার জন্য "ইনজেক্টেড" টাইপটি প্রয়োগ করেন।
টমাস আসচান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.