“নন-ভার্চুয়াল (ভিবিতে ওভারডেবল) সদস্যের উপর অবৈধ সেটআপ ...” বার্তাটি দিয়ে আমি কেন একটি ব্যতিক্রম পাচ্ছি?


176

আমার একটি ইউনিট পরীক্ষা আছে যেখানে আমাকে একটি নন-ভার্চুয়াল পদ্ধতিটি উপহাস করতে হবে যা একটি বুল টাইপ দেয়

public class XmlCupboardAccess
{
    public bool IsDataEntityInXmlCupboard(string dataId,
                                          out string nameInCupboard,
                                          out string refTypeInCupboard,
                                          string nameTemplate = null)
    {
        return IsDataEntityInXmlCupboard(_theDb, dataId, out nameInCupboard, out refTypeInCupboard, nameTemplate);
    }
}

সুতরাং আমার কাছে XmlCupboardAccessক্লাসের একটি মক অবজেক্ট রয়েছে এবং আমি নীচের মত আমার পরীক্ষার ক্ষেত্রে এই পদ্ধতির জন্য মক সেটআপ করার চেষ্টা করছি

[TestMethod]
Public void Test()
{
    private string temp1;
    private string temp2;
    private Mock<XmlCupboardAccess> _xmlCupboardAccess = new Mock<XmlCupboardAccess>();
    _xmlCupboardAccess.Setup(x => x.IsDataEntityInXmlCupboard(It.IsAny<string>(), out temp1, out temp2, It.IsAny<string>())).Returns(false); 
    //exception is thrown by this line of code
}

তবে এই রেখাটি ব্যতিক্রম ছুঁড়েছে

Invalid setup on a non-virtual (overridable in VB) member: 
x => x.IsDataEntityInXmlCupboard(It.IsAny<String>(), .temp1, .temp2, 
It.IsAny<String>())

এই ব্যতিক্রমটি পেতে কীভাবে কোনও পরামর্শ?


আপনার পরীক্ষার উপর নির্ভর করে XmlCupboardAccessকি?
প্রেস্টন গিলোট

9
এটি সহজ .. আপনার এটি চিহ্নিত করা প্রয়োজন virtual। মোখ কোনও কংক্রিটের ধরণটিকে উপেক্ষা করতে পারে না তা উপহাস করতে পারে না।
সাইমন হোয়াইটহেড

উত্তর:


265

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

আমি বিশ্বাস করি যে আপনার অন্য একটি বিষয় আপনার "কাপবোর্ডএকসেস" এর জন্য একটি ইন্টারফেস প্রবর্তন করা উচিত এবং পরিবর্তে ইন্টারফেসটিকে উপহাস করা শুরু করুন। এটি আপনাকে আপনার কোডটি দ্বিগুণ করতে সহায়তা করবে এবং দীর্ঘমেয়াদে উপকার পেতে পারে।

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


59
আপনার কেবল ইন্টারফেসের উপহাস করা উচিত এই বিষয়টির বিষয়ে +1। এই প্রশ্নটি সমাধান করেছিলাম যে আমি কী অবস্থায় চলেছি, কারণ আমি দুর্ঘটনাক্রমে ক্লাসটিকে উপহাস করেছি এবং অন্তর্নিহিত ইন্টারফেসটি নয়।
পল রাফ

1
এটি কেবল সমস্যাটিই সমাধান করে না তবে এটি আপনার পরীক্ষার প্রয়োজন এমন সমস্ত শ্রেণীর জন্য ইন্টারফেস ব্যবহার করা ভাল অনুশীলন। মোক আপনাকে মূলত ভাল নির্ভরশীলতা উল্টোপাল্টা করতে বাধ্য করে যেখানে অন্য কিছু বিদ্রূপমূলক ফ্রেমওয়ার্ক আপনাকে এই নীতিটি ঘুরে দেখার অনুমতি দেয়।
Xipooo

আমি যদি আমার ইন্টারফেসের একটি নকল প্রয়োগ, যেমন, ফেকপিয়োপল রিপোসিটরি, আইপিওপাল রিপোসিটোরি, এবং আমি নকল বাস্তবায়নকে মজা করে থাকি তবে কী এই নীতি লঙ্ঘন হিসাবে বিবেচিত হবে? আমি মনে করি আইওসি এখনও সংরক্ষিত আছে কারণ আমার পরীক্ষার সেটআপে আমাকে ভুয়া বিষয়টিকে আমার পরিষেবা শ্রেণিতে পাস করতে হবে যা এর কনস্ট্রাক্টরের ইন্টারফেস নেয়।
paz

1
@ পাজ এমওকিউ ব্যবহারের পুরো বিষয়টি হ'ল নকল প্রয়োগ এড়ানো avoid এখন বিবেচনা করুন যে জাল বাস্তবায়নের কতগুলি রূপ আপনার সীমানা শর্ত ইত্যাদি পরীক্ষা করতে হবে তত্ত্বের ক্ষেত্রে, হ্যাঁ, আপনি একটি জাল বাস্তবায়নকে উপহাস করতে পারেন। তবে কার্যত এটি একটি কোড গন্ধের মতো শোনাচ্ছে।
আমোল

নোট করুন যে এই ত্রুটিটি আসলে ইন্টারফেসগুলিতে এক্সটেনশন পদ্ধতিগুলির সাথে ঘটতে পারে, যা বিভ্রান্তিকর হতে পারে।
ড্যান প্যান্ট্রি

34

আমার মতো একই সমস্যাযুক্ত যে কোনও ব্যক্তির সহায়তা হিসাবে, আমি ঘটনাক্রমে ইন্টারফেসের পরিবর্তে বাস্তবায়নের ধরণটি ভুল টাইপ করেছি eg

var mockFileBrowser = new Mock<FileBrowser>();

পরিবর্তে

var mockFileBrowser = new Mock<IFileBrowser>();

5

দয়া করে দেখুন আমি যে সম্পত্তিটি উপহাস করতে চাই তার কেন ভার্চুয়াল হওয়া দরকার?

আপনাকে মোড়কের ইন্টারফেস লিখতে হতে পারে বা সম্পত্তিটিকে ভার্চুয়াল / অ্যাবস্ট্রাক্ট হিসাবে চিহ্নিত করতে পারে কারণ মক একটি প্রক্সি ক্লাস তৈরি করে যা এটি কলগুলিতে বাধা দেয় এবং আপনার .Returns(x)কলটিতে যে কাস্টম মান দেয় তা ফেরত দেয় uses


5

কংক্রিটের ক্লাসের বিদ্রূপ করার পরিবর্তে আপনার সেই শ্রেণি ইন্টারফেসটি উপহাস করা উচিত। এক্সএমএলক্যাপবোর্ডঅ্যাক্সেস ক্লাস থেকে ইন্টারফেস এক্সট্রাক্ট করুন

public interface IXmlCupboardAccess
{
    bool IsDataEntityInXmlCupboard(string dataId, out string nameInCupboard, out string refTypeInCupboard, string nameTemplate = null);
}

এবং পরিবর্তে

private Mock<XmlCupboardAccess> _xmlCupboardAccess = new Mock<XmlCupboardAccess>();

পরিবর্তন

private Mock<IXmlCupboardAccess> _xmlCupboardAccess = new Mock<IXmlCupboardAccess>();

3

আপনি যদি কোনও ইন্টারফেসের একটি এক্সটেনশন পদ্ধতিটি বলা হয় যা যাচাই করে যাচ্ছেন তবে আপনি এই ত্রুটিটি পেয়ে যাবেন।

উদাহরণস্বরূপ যদি আপনি উপহাস করছেন:

var mockValidator = new Mock<IValidator<Foo>>();
mockValidator
  .Verify(validator => validator.ValidateAndThrow(foo, null));

আপনি একই ব্যতিক্রম পাবেন কারণ ইন্টারফেসে .ValidateAndThrow()একটি এক্সটেনশন IValidator<T>

public static void ValidateAndThrow<T>(this IValidator<T> validator, T instance, string ruleSet = null)...


-12

কোড:

private static void RegisterServices(IKernel kernel)
{
    Mock<IProductRepository> mock=new Mock<IProductRepository>();
    mock.Setup(x => x.Products).Returns(new List<Product>
    {
        new Product {Name = "Football", Price = 23},
        new Product {Name = "Surf board", Price = 179},
        new Product {Name = "Running shose", Price = 95}
    });

    kernel.Bind<IProductRepository>().ToConstant(mock.Object);
}        

তবে ব্যতিক্রম দেখুন।


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